Maximal Rectangle

Hard
Watch on YouTube ↗

Solution

class Solution {
    public int maximalRectangle(char[][] matrix) {

        int m = matrix.length;
        int n = matrix[0].length;

        int[] height = new int[n];
        int ans = 0;

        // first row
        for (int j = 0; j < n; j++) {
            if (matrix[0][j] == '1') {
                height[j] = 1;
            }
        }
        ans = maxRectangleArea(height);

        // remaining rows
        // O(m*(n+n))
        // O(n)
        for (int i = 1; i < m; i++) {
            // accumulate heights 
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == '1') {
                    height[j]++;
                } else {
                    height[j] = 0;
                }
            }
            ans = Math.max(ans, maxRectangleArea(height));
        }

        return ans;
    }

    int maxRectangleArea(int[] height) {
        int max = 0;
        Stack<int[]> st = new Stack<>();

        for (int i = 0; i <= height.length; i++) {
            int currHeight = (i == height.length) ? 0 : height[i];
            int start = i;

            while (!st.isEmpty() && st.peek()[0] > currHeight) {
                int[] temp = st.pop();
                int h = temp[0], index = temp[1];
                // 3,3,3,1
                // 1,1,1,1 ,<1,0>,<0,4>
                // 1*4 = 4, maxarea = 9
                max = Math.max(max, h * (i - index));
                start = index;
            }
            st.push(new int[]{currHeight, start});
        }
        return max;
    }
}