zoukankan      html  css  js  c++  java
  • [leetcode]Maximal Rectangle

    这道题也不简单啊。
    这道题是在上一题基础上的扩展。可以做到O(n^2)的。首先上一题Largest Rectangle in Histogram有O(n)的解法。
    然后计算每一个位置从开始到目前有多少连续的1(假设按列算),这个可以通过O(n^2)做到,因为可以上一个加一,h[i][j-1]+1。
    接下来就是遍历每行,要注意的是之前按列算,那么现在要按行遍历。
    最后仍然超时!!即使我的代码和http://www.cnblogs.com/lichen782/p/leetcode_maximal_rectangle.html一样!!
    后来优化一下,不用stack了,用一个数组自己模拟栈,就过了。

    public class Solution {
        public int maximalRectangle(char[][] matrix) {
            int m = matrix.length;
            if (m == 0) return 0;
            int n = matrix[0].length;
            if (n == 0) return 0;
            int h[][] = new int[m][n+1]; // n+1 is for holder 0
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (matrix[i][j] == '0') {
                        h[i][j] = 0;
                    } else if (i == 0) {
                        h[i][j] = 1;
                    } else {
                        h[i][j] = h[i-1][j] + 1;
                    }
                }
            }
            int max = 0;
            for (int i = 0; i < m; i++)
            {
                int tmp = maxArea(h[i]);
                if (tmp > max) max = tmp;
            }
            return max;
        }
        
        private int maxArea(int[] h)
        {
            int max = 0;
            int[] stack = new int[h.length];
            int idx = -1;       
            int i = 0;
            while (i < h.length)
            {
                if (idx == -1 || h[i] >= h[stack[idx]])
                {
                    idx++;
                    stack[idx] = i;
                    i++;
                }
                else {
                    int t = stack[idx];
                    idx--;
                    int tmp = h[t] * (idx == -1 ? i : (i - stack[idx] - 1));
                    if (tmp > max) max = tmp;
                }
            }
            return max;
        }
    }
    

    问题是那个O(n)单调栈的算法很难想到,这样的话还有一个容易想到点的算法,复杂度是O(n^3)的,只是有些优化:http://blog.sina.com.cn/s/blog_411fed0c0100bw8m.html
    就是按行扫计算出每个位置的高度,这时回退到问题Largest Rectangle in Histogram。然后对任何一个高度向左向右扫,得到该高度能到cover的最左和最右。优化在于利用已经计算过的左侧的l[j]计算新l[j]
    一行一行的求,如果这行的第j个是1 , 这 h[j]++; 否则 h[j] = 0;
    然后对求第一行到这行的最大全1矩阵。
    例如这行的h值为 5 1 1 5 3 5 这最大全1矩阵的和应该为9。
    求这个需要两个数组 l[], r[] 分别表示以h[j]为矩阵的高的左边界和右边界:

    for(j = 0; j < m; j ++)
    {
      l[j] = j;
      while(l[j] > 0 && h[j] <= h[l[j] - 1])
      l[j] = l[l[j] - 1];
    }
    

    5 的左边界为 0。1 的左边界为1< 5, 1 的左边界肯定在5的左边界的左边 l[j] = l[l[j]–1]

    扩展阅读:http://community.topcoder.com/stat?c=problem_statement&pm=13035

  • 相关阅读:
    Excel入门
    夹缝中求和
    移动撤销
    CSP2020-j2 T4 方格取数
    CSP2020-j2 T3表达式(expr)
    直播 获奖(live)
    优秀的拆分(power)
    P5661 公交换乘
    P1160 队列安排
    P1083 借教室
  • 原文地址:https://www.cnblogs.com/lautsie/p/3286271.html
Copyright © 2011-2022 走看看