题目:
给定一个二维数组matrix,数组中的每个元素代表一棵树的高度。
你可以选定连续的若干行组成防风带,防风带每一列的防风高度为这一列的最大值
防风带整体的防风高度为,所有列防风高度的最小值。
比如,假设选定如下三行
1 5 4
7 2 6
2 3 4
1、7、2的列,防风高度为7
5、2、3的列,防风高度为5
4、6、6的列,防风高度为6
防风带整体的防风高度为5,是7、5、6中的最小值
给定一个正数k, k <= matrix的行数,表示可以取连续的k行,这k行。一起防风。
求防风带整体的防风高度最大值
思路:
这道题其实很直白,按照题意要求一步一步求就可以。每次选定连续的k行,其实就是一个窗口,防风带整体的防风高度就是选定的k行每列最大值中的最小值。遍历整个二维数组,所有的k行防风带中的最大值即是答案。
代码:
int maxHeightWindProof(vector<vector<int>> & matrix, int k) {
if (matrix.size() == 0) {
return 0;
}
int m = (int)matrix.size();
int n = (int)matrix[0].size();
int ans = INT_MAX,kAns = INT_MAX;
vector<deque<int>> windowArr(n,deque<int>());
//先求第一个k行防风带高度
//还没有窗口,每列建立窗口,外层循环是列,内层循环是行
for(int i = 0;i < n;i++) {
for(int j = 0;j < k;j++) {
while (windowArr[i].size() > 0 && matrix[j][windowArr[i].back()] <= matrix[j][i]) {
windowArr[i].pop_back();
}
windowArr[i].push_back(j);
}
//第i列的窗口最大值
kAns = min(kAns, matrix[windowArr[i].front()][i]);
}
//第一个k行防风带高度
ans = max(ans,kAns);
//已经有窗口了,每次移动一位,外层循环是行,内层循环是列
for(int j = k;j < m;j++) {
for(int i = 0;i < n;i++) {
while (windowArr[i].size() > 0 && matrix[j][windowArr[i].back()] <= matrix[j][i]) {
windowArr[i].pop_back();
}
windowArr[i].push_back(j);
while (windowArr[i].size() > 0 && j - windowArr[i].front() >= k) {
windowArr[i].pop_front();
}
//第i列的窗口最大值
kAns = min(kAns, matrix[windowArr[i].front()][i]);
}
ans = max(ans,kAns);
}
return ans;
}