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; } }
------------恢复内容结束------------