leetcode-1504-统计全1子矩形

------------恢复内容开始------------

题目描述:

 

 

 

 

 方法一:边统计边压缩:

class Solution {
    public int numSubmat(int[][] mat) {
        int row = mat.length, col = mat[0].length, ans = 0;

        for (int i = 0; i < row; i++){
            //统计
            for (int j = i; j < row; j++){
                int now = 0;
                for (int k = 0; k < col; k++){
                    if (mat[j][k] == 0) now = 0;
                    else now = k == 0 ? mat[j][0] : now + 1;
                    ans += now;
                }
            }
            //压缩
            for (int j = row - 1; j > i; j--){
                for (int k = 0; k < col; k++){
                    mat[j][k] = mat[j][k] & mat[j - 1][k];
                }
            }
        }
        return ans;
    }
}

方法二:单调栈 O(MN)

class Solution {
    public int numSubmat(int[][] mat) {
        int m = mat.length;
        int n = mat[0].length;
        // h[] records the maximum length of '1' that a cell can extends upwards
        int[] h = new int[n];
        int ans = 0;
        for (int i = 0; i < m; ++i) {
            Stack<Integer> stk = new Stack<>();
            int sum = 0;
            for (int j = 0; j < n; ++j) {
                h[j] = mat[i][j] == 1 ? 1 + h[j] : 0;
                while (!stk.empty() && h[stk.peek()] > h[j]) {
                    int idx = stk.pop();
                    int len = idx - (stk.empty() ? -1 : stk.peek());
                    sum -= len * (h[idx] - h[j]);
                }
                stk.push(j);
                sum += h[j];
                ans += sum;
            }
        }
        return ans;
    }
}

 

 

 

------------恢复内容结束------------

posted @ 2020-07-17 15:39  oldby  阅读(350)  评论(0编辑  收藏  举报