題目連接 : https://leetcode-cn.com/problems/maximal-rectangle/java
給定一個僅包含 0 和 1 的二維二進制矩陣,找出只包含 1 的最大矩形,並返回其面積python
輸入: [ ["1","0","1","0","0"], ["1","0","1","1","1"], ["1","1","1","1","1"], ["1","0","0","1","0"] ] 輸出: 6
能夠轉化和84. 柱狀圖中最大的矩形同樣,題解連接.以下圖所示:app
就是找上圖最大的矩形.spa
思路一:棧code
咱們只要遍歷每行的高度,用上一題方法(棧)求出最大矩形!blog
思路二:動態規劃leetcode
用height_j
記錄第i
行爲底,第j
列高度是多少.get
用left_j
記錄第i
行爲底, 第j
列左邊第一個小於height_j[j]
的位置io
用right_j
記錄第i
行爲底, 第j
列右邊第一個小於height_j[j]
的位置class
思路一:
class Solution: def maximalRectangle(self, matrix: List[List[str]]) -> int: if not matrix or not matrix[0]: return 0 row = len(matrix) col = len(matrix[0]) height = [0] * (col + 2) res = 0 for i in range(row): stack = [] for j in range(col + 2): if 1<=j<=col: if matrix[i][j-1] == "1": height[j] += 1 else: height[j] = 0 while stack and height[stack[-1]] > height[j]: cur = stack.pop() res = max(res, (j - stack[-1] - 1)* height[cur]) stack.append(j) return res
java
class Solution { public int maximalRectangle(char[][] matrix) { if (matrix == null || matrix.length == 0) return 0; int row = matrix.length; int col = matrix[0].length; int[] height = new int[col + 2]; int res = 0; for (int i = 0; i < row; i++) { Deque<Integer> stack = new ArrayDeque<>(); for (int j = 0; j < col + 2; j++) { if (j >= 1 && j <= col) { if (matrix[i][j-1] == '1') height[j] += 1; else height[j] = 0; } while (!stack.isEmpty() && height[stack.peek()] > height[j]) { int cur = stack.pop(); res = Math.max(res, (j - stack.peek() - 1) * height[cur]); } stack.push(j); } } return res; } }
思路二:
class Solution: def maximalRectangle(self, matrix: List[List[str]]) -> int: if not matrix or not matrix[0]: return 0 row = len(matrix) col = len(matrix[0]) left_j = [-1] * col right_j = [col] * col height_j = [0] * col res = 0 for i in range(row): cur_left = -1 cur_right = col for j in range(col): if matrix[i][j] == "1": height_j[j] += 1 else: height_j[j] = 0 for j in range(col): if matrix[i][j] == "1": left_j[j] = max(left_j[j], cur_left) else: left_j[j] = -1 cur_left = j for j in range(col - 1, -1, -1): if matrix[i][j] == "1": right_j[j] = min(right_j[j], cur_right) else: right_j[j] = col cur_right = j for j in range(col): res = max(res, (right_j[j] - left_j[j] - 1) * height_j[j]) return res
java
class Solution { public int maximalRectangle(char[][] matrix) { if (matrix == null || matrix.length == 0) return 0; int row = matrix.length; int col = matrix[0].length; int[] left_j = new int[col]; Arrays.fill(left_j, -1); int[] right_j = new int[col]; Arrays.fill(right_j, col); int[] height_j = new int[col]; int res = 0; for (int i = 0; i < row; i++) { int cur_left = -1; int cur_right = col; for (int j = 0; j < col; j++) { if (matrix[i][j] == '1') height_j[j] += 1; else height_j[j] = 0; } for (int j = 0; j < col; j++) { if (matrix[i][j] == '1') left_j[j] = Math.max(left_j[j], cur_left); else { left_j[j] = -1; cur_left = j; } } for (int j = col - 1; j >= 0; j--) { if (matrix[i][j] == '1') right_j[j] = Math.min(right_j[j], cur_right); else { right_j[j] = col; cur_right = j; } } for (int j = 0; j < col; j++) res = Math.max(res, (right_j[j] - left_j[j] - 1) * height_j[j]); } return res; } }