[LeetCode] 85. Maximal Rectangle_Hard tag: Dynamic Programming

发布时间 2023-09-14 08:34:43作者: Johnson_强生仔仔

Given a rows x cols binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.

 

Example 1:

Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
Output: 6
Explanation: The maximal rectangle is shown in the above picture.

Example 2:

Input: matrix = [["0"]]
Output: 0

Example 3:

Input: matrix = [["1"]]
Output: 1

 

Constraints:

  • rows == matrix.length
  • cols == matrix[i].length
  • 1 <= rows, cols <= 200
  • matrix[i][j] is '0' or '1'.

 

思路参考solution,用3个n size 的array:

height: height[i] 表明当前row的第i个元素往上走最高的height

left:left[i] 表明当前row的第i个元素height 的left most index; 相当于 for k in [left[i], i] s.t height[k] >= height[i]

right: right[i] 表明当前row的第i个元素height 的right most index; 相当于 for k in [i, right[i]] s.t height[k] >= height[i]

each area = height[i] * (right[i] - left[i] + 1)

Code:

class Solution:
    def maximalRectangle(self, matrix: List[List[str]]) -> int:
        m, n = len(matrix), len(matrix[0])
        left = [0] * n
        right = [n - 1] * n
        height = [0] * n
        ans = 0

        for i in range(m):
            cur_left, cur_right = 0, n - 1
            # update height
            for j in range(n):
                if matrix[i][j] == '1':
                    height[j] += 1
                else:
                    height[j] = 0
            # update left, when matrix[i][j] == '1', we need to compare cur_left with last row left most index, which is left[i]
            for j in range(n):
                if matrix[i][j] == '1':
                    left[j] = max(cur_left, left[j])
                else:
                    left[j] = 0
                    cur_left = j + 1
            # update right
            for j in range(n - 1, -1, -1):
                if matrix[i][j] == '1':
                    right[j] = min(cur_right, right[j])
                else:
                    right[j] = n - 1
                    cur_right = j - 1
            # update the area
            for j in range(n):
                ans = max(ans, height[j] * (right[j] - left[j] + 1))
        return ans