力扣算法题—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 }

原文地址:https://www.cnblogs.com/zzw1024/p/10743338.html

时间: 2024-08-30 07:17:26

力扣算法题—085最大矩阵的相关文章

力扣算法题—042接雨水

1 #include"000库函数.h" 2 //一点头绪都没有 3 //然后就自己按自己的意思来一遍 4 //好像没有用算法 5 //16ms,让我激动一把 6 7 class Solution { 8 public: 9 int trap(vector<int>& height) { 10 if (height.size() < 2)return 0; 11 int s = 0;//起始点 12 int e = 0;//终止点 13 int v = 0;/

力扣算法题—048旋转图像

1 #include "000库函数.h" 2 3 //找位置规律 4 //先不按照规则,使用另一个矩阵 5 class Solution { 6 public: 7 void rotate(vector<vector<int>>& matrix) { 8 vector < vector<int>>v = matrix; 9 int n = matrix.size(); 10 for (int t = 0; t < 1; +

力扣算法题—050计算pow(x, n)

1 #include "000库函数.h" 2 3 4 5 //使用折半算法 牛逼算法 6 class Solution { 7 public: 8 double myPow(double x, int n) { 9 if (n == 0)return 1; 10 double res = 1.0; 11 for (int i = n; i != 0; i /= 2) { 12 if (i % 2 != 0) 13 res *= x; 14 x *= x; 15 } 16 return

力扣算法题—064最小路径之和

给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入: [   [1,3,1], [1,5,1], [4,2,1] ] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小. 1 #include "_000库函数.h" 2 3 //使用Dijkstra算法 4 //即动态规划 5 class Solution { 6 public: 7 int minPathSum(vec

力扣算法题—147Insertion_Sort_List

Sort a linked list using insertion sort. A graphical example of insertion sort. The partial sorted list (black) initially contains only the first element in the list.With each iteration one element (red) is removed from the input data and inserted in

力扣算法题—062不同路径

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为“Finish”). 问总共有多少条不同的路径? 例如,上图是一个7 x 3 的网格.有多少可能的路径? 说明:m 和 n 的值均不超过 100. 示例 1: 输入: m = 3, n = 2 输出: 3 解释: 从左上角开始,总共有 3 条路径可以到达右下角. 1. 向右 -> 向右 -> 向下 2. 向右 -> 向下

力扣算法题—072编辑距离

给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 . 你可以对一个单词进行如下三种操作: 插入一个字符 删除一个字符 替换一个字符 示例 1: 输入: word1 = "horse", word2 = "ros" 输出: 3 解释: horse -> rorse (将 'h' 替换为 'r') rorse -> rose (删除 'r') rose -> ros (删除 'e') 示例 2: 输

力扣算法题—078集合

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3] 输出: [ [3],   [1],   [2],   [1,2,3],   [1,3],   [2,3],   [1,2],   [] ] 1 #include "_000库函数.h" 2 3 4 //这道题就是求不同的子集问题 5 class solution { 6 public: 7 vector<vector<i

力扣算法题—092反转链表2

反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明:1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5->NULL, m = 2, n = 4 输出: 1->4->3->2->5->NULL 1 #include "_000库函数.h" 2 3 4 struct ListNode { 5 int val; 6 ListNode *next; 7 ListNode(int x) : val