|
|
package class_2022_07_1_week;
|
|
|
|
|
|
// 来自真实笔试
|
|
|
// 给定一个二维数组matrix,数组中的每个元素代表一棵树的高度。
|
|
|
// 你可以选定连续的若干行组成防风带,防风带每一列的防风高度为这一列的最大值
|
|
|
// 防风带整体的防风高度为,所有列防风高度的最小值。
|
|
|
// 比如,假设选定如下三行
|
|
|
// 1 5 4
|
|
|
// 7 2 6
|
|
|
// 2 3 4
|
|
|
// 1、7、2的列,防风高度为7
|
|
|
// 5、2、3的列,防风高度为5
|
|
|
// 4、6、4的列,防风高度为6
|
|
|
// 防风带整体的防风高度为5,是7、5、6中的最小值
|
|
|
// 给定一个正数k,k <= matrix的行数,表示可以取连续的k行,这k行一起防风。
|
|
|
// 求防风带整体的防风高度最大值
|
|
|
public class Code01_WindPrevent {
|
|
|
|
|
|
public static int bestHeight1(int[][] matrix, int k) {
|
|
|
int n = matrix.length;
|
|
|
int m = matrix[0].length;
|
|
|
int ans = 0;
|
|
|
for (int startRow = 0; startRow < n; startRow++) {
|
|
|
int bottleNeck = Integer.MAX_VALUE;
|
|
|
for (int col = 0; col < m; col++) {
|
|
|
int height = 0;
|
|
|
for (int endRow = startRow; endRow < n && (endRow - startRow + 1 <= k); endRow++) {
|
|
|
height = Math.max(height, matrix[endRow][col]);
|
|
|
}
|
|
|
bottleNeck = Math.min(bottleNeck, height);
|
|
|
}
|
|
|
ans = Math.max(ans, bottleNeck);
|
|
|
}
|
|
|
return ans;
|
|
|
}
|
|
|
|
|
|
// public static class WindowManager {
|
|
|
//
|
|
|
// // 建立出m个窗口!
|
|
|
// public WindowManager(int m) {
|
|
|
//
|
|
|
// }
|
|
|
//
|
|
|
// public void addRow(int[][] matrix, int row) {
|
|
|
//
|
|
|
// }
|
|
|
//
|
|
|
// public void deleteRow(int[][] matrix, int row) {
|
|
|
//
|
|
|
// }
|
|
|
//
|
|
|
// public int getAllWindowMaxMin() {
|
|
|
// return 100;
|
|
|
// }
|
|
|
//
|
|
|
// }
|
|
|
//
|
|
|
// public static int bestWindHeight(int[][] matrix, int k) {
|
|
|
// int n = matrix.length;
|
|
|
// int m = matrix[0].length;
|
|
|
// k = Math.min(k, n);
|
|
|
// WindowManager windowManager = new WindowManager(m);
|
|
|
// for (int i = 0; i < k - 1; i++) {
|
|
|
// windowManager.addRow(matrix, i);
|
|
|
// }
|
|
|
// int ans = 0;
|
|
|
// for (int i = k - 1; i < n; i++) {
|
|
|
// windowManager.addRow(matrix, i);
|
|
|
// int cur = windowManager.getAllWindowMaxMin();
|
|
|
// ans = Math.max(ans, cur);
|
|
|
// windowManager.deleteRow(matrix, i - k + 1);
|
|
|
// }
|
|
|
// return ans;
|
|
|
// }
|
|
|
|
|
|
public static int bestHeight2(int[][] matrix, int k) {
|
|
|
int n = matrix.length;
|
|
|
int m = matrix[0].length;
|
|
|
int[][] windowMaxs = new int[m][n];
|
|
|
int[][] windowLR = new int[m][2];
|
|
|
for (int i = 0; i < k; i++) {
|
|
|
addRow(matrix, m, i, windowMaxs, windowLR);
|
|
|
}
|
|
|
int ans = bottleNeck(matrix, m, windowMaxs, windowLR);
|
|
|
for (int i = k; i < n; i++) {
|
|
|
addRow(matrix, m, i, windowMaxs, windowLR);
|
|
|
deleteRow(m, i - k, windowMaxs, windowLR);
|
|
|
ans = Math.max(ans, bottleNeck(matrix, m, windowMaxs, windowLR));
|
|
|
}
|
|
|
return ans;
|
|
|
}
|
|
|
|
|
|
public static void addRow(int[][] matrix, int m, int row, int[][] windowMaxs, int[][] windowLR) {
|
|
|
for (int col = 0; col < m; col++) {
|
|
|
while (windowLR[col][0] != windowLR[col][1]
|
|
|
&& matrix[windowMaxs[col][windowLR[col][1] - 1]][col] <= matrix[row][col]) {
|
|
|
windowLR[col][1]--;
|
|
|
}
|
|
|
windowMaxs[col][windowLR[col][1]++] = row;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static void deleteRow(int m, int row, int[][] windowMaxs, int[][] windowLR) {
|
|
|
for (int col = 0; col < m; col++) {
|
|
|
if (windowMaxs[col][windowLR[col][0]] == row) {
|
|
|
windowLR[col][0]++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static int bottleNeck(int[][] matrix, int m, int[][] windowMaxs, int[][] windowLR) {
|
|
|
int ans = Integer.MAX_VALUE;
|
|
|
for (int col = 0; col < m; col++) {
|
|
|
ans = Math.min(ans, matrix[windowMaxs[col][windowLR[col][0]]][col]);
|
|
|
}
|
|
|
return ans;
|
|
|
}
|
|
|
|
|
|
public static int[][] generateMatrix(int n, int m, int v) {
|
|
|
int[][] matrix = new int[n][m];
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
for (int j = 0; j < m; j++) {
|
|
|
matrix[i][j] = (int) (Math.random() * v) + 1;
|
|
|
}
|
|
|
}
|
|
|
return matrix;
|
|
|
}
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
int nMax = 10;
|
|
|
int mMax = 10;
|
|
|
int vMax = 50;
|
|
|
int testTimes = 1000;
|
|
|
System.out.println("测试开始");
|
|
|
for (int i = 0; i < testTimes; i++) {
|
|
|
int n = (int) (Math.random() * nMax) + 1;
|
|
|
int m = (int) (Math.random() * mMax) + 1;
|
|
|
int[][] matrix = generateMatrix(n, m, vMax);
|
|
|
int k = (int) (Math.random() * n) + 1;
|
|
|
int ans1 = bestHeight1(matrix, k);
|
|
|
int ans2 = bestHeight2(matrix, k);
|
|
|
if (ans1 != ans2) {
|
|
|
System.out.println("出错了!");
|
|
|
}
|
|
|
}
|
|
|
System.out.println("测试结束");
|
|
|
}
|
|
|
|
|
|
}
|