LeetCode 85

问题描述:

给定一个只包含0和1的二维数组,找到只包含1的最大矩形。

例子:

Input:
[
  ["1","0","1","0","0"],
  ["1","0","1","1","1"],
  ["1","1","1","1","1"],
  ["1","0","0","1","0"]
]
Output: 6

解法:

1. 动态规划:

这道题可以用动态规划的方法来解决。对于矩阵中的每个为1的点,以该点为起点向上连一条最长的只包含1的直线。求出包含该直线最大的矩形的面积。所有面积中最大的即为所求。以下图为例,红色点对应的面积即为绿色框所显示的区域。

leetcode 85

为了实现上面的思路,我们只需要维护三个标记为left、right、hight的矩阵。面积即为hight * (right - left)。

[cur_left, cur_right) // 当前行包含该点最长的连续1区间

left(i, j) = max(left(i-1, j), cur_left)

right(i, j) = min(right(i-1, j), cur_right)

height(i, j) += 1, if matrix[i][j]==’1’;

height(i, j) = 0, if matrix[i][j]==’0’

以上面的例子为例,最终left、right、hight三个矩阵分别为:

# left
[0, 0, 2, 0, 0]
[0, 0, 2, 2, 2]
[0, 0, 2, 2, 2]
[0, 0, 0, 3, 0]

# right
[1, 5, 3, 5, 5]
[1, 5, 3, 5, 5]
[1, 5, 3, 5, 5]
[1, 5, 5, 4, 5]

# height
[1, 0, 1, 0, 0]
[2, 0, 2, 1, 1]
[3, 1, 3, 2, 2]
[4, 0, 0, 3, 0]

代码实现:

class Solution(object):
    def maximalRectangle(self, matrix):
        """
        :type matrix: List[List[str]]
        :rtype: int
        """

        if not matrix:
            return 0

        # DP
        m, n = len(matrix), len(matrix[0])
        left = [0] * n
        right = [n] * n
        hight = [0] * n
        max_area = 0

        for i in range(m):

            # left
            curr_left= 0
            for j in range(n):
                if matrix[i][j] == '1':
                    left[j] = max(curr_left, left[j])
                else:
                    left[j] = 0
                    curr_left = j + 1

            # right
            curr_right = n
            for j in range(n - 1, -1, -1):
                if matrix[i][j] == '1':
                    right[j] = min(curr_right, right[j])
                else:
                    right[j] = n
                    curr_right = j

            # hight
            for j in range(n):
                if matrix[i][j] == '1':
                    hight[j] += 1
                else:
                    hight[j] = 0

            # area
            for j in range(n):
                curr_area = (right[j] - left[j]) * hight[j]
                max_area = max(max_area, curr_area)

        return max_area

2. 基于LeetCode 84题的O(n^2)解法

对于每一行构造出以当前行为底的柱状图,然后利用LeetCode 84题的解法,对每一行求解。最终求出最大的矩形。以下图为例,对于红色行,构造的柱形图即为绿色框所围起来的。

LeetCode85_1

代码实现:

class Solution(object):
    def maximalRectangle(self, matrix):
        """
        :type matrix: List[List[str]]
        :rtype: int
        """

        if not matrix:
            return 0

        m, n = len(matrix), len(matrix[0])
        height = [0] * (n + 1)

        ans = 0
        for i in range(m):
            for j in range(n):
                if matrix[i][j] == '1':
                    height[j] += 1
                else:
                    height[j] = 0

            # solution for LeetCode 84
            stack = [-1]
            for j in range(n + 1):
                while height[j] < height[stack[-1]]:
                    h = height[stack.pop()]
                    w = j - stack[-1] - 1
                    ans = max(ans, w * h)
                stack.append(j)

        return ans

  转载请注明: 石锅拌饭 LeetCode 85

 上一篇
遍历二叉树 遍历二叉树
二叉树的知识点及遍历方法整理。 1. 什么是二叉树? 二叉树是每个结点最多有两个分支的树结构。通常被称作“左子树”和“右子树”。二叉树的分支具有左右次序,不能随意颠倒。 2. 二叉树种类2.1 斜树 所有节点只有左子树,或者右子树。 2
2018-12-10
下一篇 
如何修改Hexo主题 如何修改Hexo主题
这几天使用hexo-theme-matery的主题搭建Blog时,发现主题的很多设计不是很喜欢。所以就想自己动手改一下,于是也就有了这篇博客。在讲修改之前先说一下如果你和我一样也是0基础,却想要修改别人的主题,要做哪些准备。 准备工作:我们
2018-12-07
  目录