5
public int numSubmat(int[][] mat) {6
this.n = mat[0].length;8
// dp[j] : the height (number of consecutive '1's) of column j10
for (int i = 0; i < mat.length; i++) {11
// calculating (updating) heights12
for (int j = 0; j < n; j++) {13
dp[j] = mat[i][j] == 1 ? dp[j] + 1 : 0;15
enumerateRowByMinHeight(dp);20
public void enumerateRowByMinHeight(int[] dp) {21
// monotonic stack storing indices : for index p < q in stack, dp[p] < dp[q]22
Deque<Integer> stack = new LinkedList<>();25
for (int j = 0; j < n; j++) {26
while (stack.peekLast() != -1 && dp[stack.peekLast()] >= dp[j]) {27
int idx = stack.pollLast();28
res += dp[idx] * (idx - stack.peekLast()) * (j - idx);32
while (stack.peekLast() != -1) {33
int idx = stack.pollLast();34
res += dp[idx] * (idx - stack.peekLast()) * (n - idx);