221. Maximal Square && 85. Maximal Rectangle && 84. Largest Rectangle in Histogram

221. Maximal Square

Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area.

For example, given the following matrix:

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 4. 

Hide Tags

 
public class Solution {
  /**
   * dp[i][j] denotes the maximal size of the square that can be achieved at point (i, j)
   * dp[0][j] = matrix[0][j] (topmost row)
   * dp[i][0] = matrix[i][0] (leftmost column)
   * For i > 0 and j > 0:
   * if matrix[i][j] = 0, dp[i][j] = 0
   * if matrix[i][j] = 1, dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
   */
  public int maximalSquare(char[][] matrix) {
    if (matrix.length == 0)
      return 0;
    int row = matrix.length;
    int col = matrix[0].length;

    int maxLen = 0;
    int[][] dp = new int[row][col];
    for (int c = 0; c < col; ++c) {
      dp[0][c] = matrix[0][c] - '0';
      maxLen = Math.max(maxLen, dp[0][c]);
    }
    for (int r = 1; r < row; ++r) {
      dp[r][0] = matrix[r][0] - '0';
      maxLen = Math.max(maxLen, dp[r][0]);
    }

    for (int r = 1; r < row; ++r) {
      for (int c = 1; c < col; ++c) {
        if (matrix[r][c] == '1') {
          dp[r][c] = Math.min(Math.min(dp[r][c - 1], dp[r - 1][c - 1]), dp[r - 1][c]) + 1;
          maxLen = Math.max(dp[r][c], maxLen); // update maxLen
        }
      }
    }
    return maxLen * maxLen;
  }
}

 

85. Maximal Rectangle

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.

For example, given the following matrix:

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 6.

Hide Tags

 
public class Solution {
  public int maximalRectangle(char[][] matrix) {
    if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
      return 0;

    int[] height = new int[matrix[0].length];
    for (int c = 0; c < matrix[0].length; ++c) {
      if (matrix[0][c] == '1')
        height[c] = 1;
    }

    int maxArea = largestRectangleArea(height);
    for (int r = 1; r < matrix.length; ++r) {
      //convert the problem to 84. Largest Rectangle in Histogram
      //transform the range [row_0, row_r] to histograms.
      for (int c = 0; c < matrix[0].length; ++c) {
        if (matrix[r][c] == '1')
          height[c] += 1;
        else height[c] = 0;
      }
      //get the maximum area for each row of histogram.
      maxArea = Math.max(maxArea, largestRectangleArea(height));
    }

    return maxArea;
  }

  private int largestRectangleArea(int[] height) {
    int len = height.length;
    Stack<Integer> s = new Stack<>();
    int maxArea = 0;
    for (int i = 0; i <= len; ++i) {
      int h = (i == len ? 0 : height[i]);  //height of the synthetic "termination bar" is 0.
      //when current bar is higher, we can continue to look to the right
      if (s.isEmpty() || h >= height[s.peek()]) {
        s.push(i);
      }
      //when current bar is lower, it is good enough to determine areas for bars, which are to the left and lower than current bar.
      else {
        int stackTopHeight = height[s.pop()];
        //right index is the index of the first bar, which is less than and to the right of current bar
        int rightIndex = i;
        //left index is the index of the first bar, which is less than and to the left of current bar
        int leftIndex = s.isEmpty() ? -1 : s.peek();
        int width = rightIndex - leftIndex - 1;
        maxArea = Math.max(maxArea, stackTopHeight * width);
        --i; //keep i the same for next loop
      }
    }
    return maxArea;
  }
}

 

 
 

 

 

84. Largest Rectangle in Histogram

This can be treated as a special case of 85 where the last row is all ones.

Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.

Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]

The largest rectangle is shown in the shaded area, which has area = 10 unit.

For example,
Given heights = [2,1,5,6,2,3],
return 10.

 
Hide Tags
 Array Stack
 
Check this for two solutions: http://www.geeksforgeeks.org/largest-rectangle-under-histogram/
 
1. O(nlogn) Divide and Conquer solution:
The idea is to find the minimum value in the given array.
(Use segment tree to find minimum in a range. http://www.geeksforgeeks.org/segment-tree-set-1-range-minimum-query/)
Once we have index of the minimum value, the max area is maximum of following three values.
a) Maximum area in left side of minimum value (Not including the min value)
b) Maximum area in right side of minimum value (Not including the min value)
c) Number of bars multiplied by minimum value.
 
2. Stack based.
public class Solution {
  //calculate the maximum area for each bar by looking at the right side.
  public int largestRectangleArea(int[] height) {
    int len = height.length;
    Stack<Integer> s = new Stack<>();
    int maxArea = 0;
    for (int i = 0; i <= len; ++i) {
      int h = (i == len ? 0 : height[i]);  //height of the synthetic "termination bar" is 0.
      //when current bar is higher, we can continue to look to the right
      if (s.isEmpty() || h >= height[s.peek()]) {
        s.push(i);
      }
      //when current bar is lower, it is good enough to determine areas for bars, which are to the left and lower than current bar.
      else {
        int stackTopHeight = height[s.pop()];
        //right index is the index of the first bar, which is less than and to the right of current bar
        int rightIndex = i;
        //left index is the index of the first bar, which is less than and to the left of current bar
        int leftIndex = s.isEmpty() ? -1 : s.peek();
        int width = rightIndex - leftIndex - 1;
        maxArea = Math.max(maxArea, stackTopHeight * width);
        --i; //keep i the same for next loop
      }
    }
    return maxArea;
  }
}

 

 
 
 
 
 
posted @ 2016-07-27 13:58  新一代的天皇巨星  阅读(245)  评论(0)    收藏  举报