力扣算法题—085最大矩阵
Posted zzw1024
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣算法题—085最大矩阵相关的知识,希望对你有一定的参考价值。
给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
示例:
输入: [ ["1","0","1","0","0"], ["1","0","1","1","1"], ["1","1","1","1","1"], ["1","0","0","1","0"] ] 输出: 6
1 #include "_000库函数.h" 2 3 4 //竟然通过了,我还以为会挂了 5 //使用左上角指针和右下角指针组成矩阵的左上角和右下角 6 //["1", "0", "1", "0", "0"], 7 // 8 //["1", "0", "1", "1", "1"], 9 // start-> //左上角从每行最左d端开始遍历 10 //["1", "1", "1", "1", "1"], 11 // end-> //右下角从start 的列开始每行遍历 12 //["1", "0", "0", "1", "0"] 13 //为了避免将0包进去,用minPot记录离start最近的0列,则右侧不用再遍历 14 15 class Solution { 16 public: 17 int maximalRectangle(vector<vector<char>>& matrix) { 18 int res = 0; 19 for (int i = 0; i < matrix.size(); ++i) {//左上角遍历的行 20 for (int start = 0; start < matrix[0].size(); ++start) {//左上角从每行的最左端开始遍历 21 if (matrix[i][start] == ‘0‘)continue; 22 int minRight = matrix[0].size();//记录右下角的位置,防止矩阵将0包含进去 23 for (int j = i; j < matrix.size(); ++j) {//右右下角的遍历行 24 for (int end = start; end < minRight; ++end) {//右下角从左上角的列开始遍历 25 if (matrix[j][end] == ‘0‘) { 26 minRight = minRight > end ? end : minRight; 27 break; 28 } 29 res = res > ((end - start + 1)*(j - i + 1)) ? res : ((end - start + 1)*(j - i + 1)); 30 } 31 } 32 } 33 } 34 return res; 35 } 36 }; 37 38 //这道题的二维矩阵每一层向上都可以看做一个直方图,输入矩阵有多少行,就可以形成多少个直方图 39 class Solution { 40 public: 41 int maximalRectangle(vector<vector<char>>& matrix) { 42 if (matrix.empty() || matrix[0].empty()) return 0; 43 int res = 0, m = matrix.size(), n = matrix[0].size(); 44 vector<int> height(n + 1, 0); 45 for (int i = 0; i < m; ++i) { 46 stack<int> s; 47 for (int j = 0; j < n + 1; ++j) { 48 if (j < n) { 49 height[j] = matrix[i][j] == ‘1‘ ? height[j] + 1 : 0; 50 } 51 while (!s.empty() && height[s.top()] >= height[j]) { 52 int cur = s.top(); s.pop(); 53 res = max(res, height[cur] * (s.empty() ? j : (j - s.top() - 1))); 54 } 55 s.push(j); 56 } 57 } 58 return res; 59 } 60 }; 61 62 //下面这种方法的思路很巧妙,height数组和上面一样, 63 //这里的left数组表示左边界是1的位置,right数组表示右边界是1的位置, 64 //那么对于任意一行的第j个位置,矩形为(right[j] - left[j]) * height[j], 65 //我们举个例子来说明,比如给定矩阵为: 66 //[ 67 // [1, 1, 0, 0, 1], 68 // [0, 1, 0, 0, 1], 69 // [0, 0, 1, 1, 1], 70 // [0, 0, 1, 1, 1], 71 // [0, 0, 0, 0, 1] 72 //] 73 //第0行: 74 // 75 //h : 1 1 0 0 1 76 // l : 0 0 0 0 4 77 // r : 2 2 5 5 5 78 // 79 // 80 // 第1行: 81 // 82 // h : 1 1 0 0 1 83 // l : 0 0 0 0 4 84 // r : 2 2 5 5 5 85 // 86 // 87 // 第2行: 88 // 89 // h : 0 0 1 1 3 90 // l : 0 0 2 2 4 91 // r : 5 5 5 5 5 92 // 93 // 94 // 第3行: 95 // 96 // h : 0 0 2 2 4 97 // l : 0 0 2 2 4 98 // r : 5 5 5 5 5 99 // 100 // 101 // 第4行: 102 // 103 // h : 0 0 0 0 5 104 // l : 0 0 0 0 4 105 // r : 5 5 5 5 5 106 107 class Solution { 108 public: 109 int maximalRectangle(vector<vector<char>>& matrix) { 110 if (matrix.empty() || matrix[0].empty()) return 0; 111 int res = 0, m = matrix.size(), n = matrix[0].size(); 112 vector<int> height(n, 0), left(n, 0), right(n, n); 113 for (int i = 0; i < m; ++i) { 114 int cur_left = 0, cur_right = n; 115 for (int j = 0; j < n; ++j) { 116 if (matrix[i][j] == ‘1‘) { 117 ++height[j]; 118 left[j] = max(left[j], cur_left); 119 } 120 else { 121 height[j] = 0; 122 left[j] = 0; 123 cur_left = j + 1; 124 } 125 } 126 for (int j = n - 1; j >= 0; --j) { 127 if (matrix[i][j] == ‘1‘) { 128 right[j] = min(right[j], cur_right); 129 } 130 else { 131 right[j] = n; 132 cur_right = j; 133 } 134 res = max(res, (right[j] - left[j]) * height[j]); 135 } 136 } 137 return res; 138 } 139 }; 140 141 void T085() { 142 Solution s; 143 vector<vector<char>>v; 144 v = { 145 {‘1‘,‘0‘,‘1‘,‘0‘,‘0‘}, 146 {‘1‘,‘0‘,‘1‘,‘1‘,‘1‘}, 147 {‘1‘,‘1‘,‘1‘,‘1‘,‘1‘}, 148 {‘1‘,‘0‘,‘0‘,‘1‘,‘0‘} 149 }; 150 cout << s.maximalRectangle(v) << endl; 151 152 }
以上是关于力扣算法题—085最大矩阵的主要内容,如果未能解决你的问题,请参考以下文章