mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
add solution 5
This commit is contained in:
parent
6f35069c39
commit
af4b9b1bfc
@ -39,6 +39,17 @@
|
|||||||
|
|
||||||
时间复杂度O(n^2), 空间复杂度O(n)。
|
时间复杂度O(n^2), 空间复杂度O(n)。
|
||||||
|
|
||||||
|
## 思路五、转换成求直方图包含的最大正方形
|
||||||
|
|
||||||
|
这题和[85. Maximal Rectangle](https://leetcode.com/problems/maximal-rectangle/)有点像,不同点就是85题只需要矩形而本题要求区域是正方形。如果把二维矩阵的第 i 行及上面的部分可以看成是一个直方图,那么85题又转化成了[84. Largest Rectangle in Histogram](https://leetcode.com/problems/largest-rectangle-in-histogram/)(见[85题思路一](85.%20Maximal%20Rectangle.md))。顺着这个思路,我们也可以利用84题来解此题。
|
||||||
|
|
||||||
|
具体来说,我们把二维矩阵的第 i 行及上面的部分可以看成是一个直方图(假设用数组hs表示),然后采用[84思路一](84.%20Largest%20Rectangle%20in%20Histogram.md)求出直方图里包含的最大正方形:
|
||||||
|
求出`hs[i]`向左第一个比他小的数`hs[j1]`和向右第一个比他小的数`hs[j2]`。那么此时能容纳的正方形的边长就为高和宽的较小者,即`min(heights[i], j2 - j1 - 1)`。
|
||||||
|
|
||||||
|
求数组中每个元素的左(右)边第一个比他大(小)的元素可利用单调栈在O(n)时间内求出,关于单调栈可以参考[我的总结](../algorithm/array/monotonic_stack_queue.md)。
|
||||||
|
|
||||||
|
|
||||||
|
总的时间复杂度O(n^2), 空间复杂度O(n)。
|
||||||
|
|
||||||
## 思路一
|
## 思路一
|
||||||
``` C++
|
``` C++
|
||||||
@ -157,3 +168,47 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 思路五
|
||||||
|
``` C++
|
||||||
|
class Solution {
|
||||||
|
private:
|
||||||
|
int helper(const vector<int>&hs){ // 求直方图能容纳的最大正方形, 类似84题
|
||||||
|
int n = hs.size(), max_l = 0;
|
||||||
|
vector<int>pre_smaller(n, -1), next_smaller(n, n); // 存的是下标
|
||||||
|
stack<int>stk1, stk2; // 存的也是下标
|
||||||
|
|
||||||
|
for(int i = 0; i < n; i++){
|
||||||
|
while(!stk1.empty() && hs[stk1.top()] >= hs[i]) stk1.pop();
|
||||||
|
if(!stk1.empty()) pre_smaller[i] = stk1.top();
|
||||||
|
stk1.push(i);
|
||||||
|
|
||||||
|
int j = n - i - 1; // 相当于反向遍历: for(int j = n-1; j >= 0; j--)
|
||||||
|
while(!stk2.empty() && hs[stk2.top()] >= hs[j]) stk2.pop();
|
||||||
|
if(!stk2.empty()) next_smaller[j] = stk2.top();
|
||||||
|
stk2.push(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < n; i++)
|
||||||
|
max_l = max(max_l, min(hs[i], next_smaller[i] - pre_smaller[i] - 1));
|
||||||
|
|
||||||
|
return max_l * max_l;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
int maximalSquare(vector<vector<char>>& matrix) {
|
||||||
|
if(matrix.empty()) return 0;
|
||||||
|
int m = matrix.size(), n = matrix[0].size(), res = 0;
|
||||||
|
|
||||||
|
vector<int>hs(n, 0);
|
||||||
|
|
||||||
|
for(int i = 0; i < m; i++){
|
||||||
|
for(int j = 0; j < n; j++){
|
||||||
|
if(matrix[i][j] == '1') hs[j]++;
|
||||||
|
else hs[j] = 0;
|
||||||
|
}
|
||||||
|
res = max(res, helper(hs));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user