diff --git "a/topic01/submit/LC85_\350\251\271\345\271\277\350\266\205.cpp" "b/topic01/submit/LC85_\350\251\271\345\271\277\350\266\205.cpp" new file mode 100644 index 0000000000000000000000000000000000000000..8b9e2480a63e3346480d8c7ac8db8dcae5ddd07e --- /dev/null +++ "b/topic01/submit/LC85_\350\251\271\345\271\277\350\266\205.cpp" @@ -0,0 +1,81 @@ +#include +#include +#include +using namespace std; + +//【题目】力扣85.最大矩形 +//【难度】困难 +//【提交】https://leetcode.cn/problems/maximal-rectangle/submissions/664056286/ +//【标签】栈;数组;动态规划;矩阵;单调栈 +class Solution +{ +public: + int maximalRectangle(vector>& matrix) + { + int m = matrix.size(); + if (m == 0) + { + return 0; + } + int n = matrix[0].size(); + vector> left(m, vector(n, 0)); + + for (int i = 0; i < m; i++) + { + for (int j = 0; j < n; j++) + { + if (matrix[i][j] == '1') + { + left[i][j] = (j == 0 ? 0 : left[i][j - 1]) + 1; + } + } + } + + int ret = 0; + for (int j = 0; j < n; j++) + { + vector up(m, 0), down(m, 0); + + stack stk; + for (int i = 0; i < m; i++) + { + while (!stk.empty() && left[stk.top()][j] >= left[i][j]) + { + stk.pop(); + } + up[i] = stk.empty() ? -1 : stk.top(); + stk.push(i); + } + stk = stack(); + for (int i = m - 1; i >= 0; i--) + { + while (!stk.empty() && left[stk.top()][j] >= left[i][j]) + { + stk.pop(); + } + down[i] = stk.empty() ? m : stk.top(); + stk.push(i); + } + + for (int i = 0; i < m; i++) + { + int height = down[i] - up[i] - 1; + int area = height * left[i][j]; + ret = max(ret, area); + } + } + return ret; + } +}; + +/* +学习总结: +代码核心思路分为两步: +预处理: +通过动态规划计算每个位置(i, j)左侧连续1的个数(包括自身),存储在left数组中。 +这一步将问题转化为多个“柱状图中最大矩形”问题。 + +单调栈应用:对于每一列j,将left[i][j]视为柱状图的高度 +利用单调栈分别求出每个高度向左和向右的边界(即第一个小于当前高度的位置) +从而计算以当前高度为矩形的最大面积,并更新全局最大值。 +*/ \ No newline at end of file