力扣85-最大矩形(巧妙利用上一題解答 Java版題解)

ItDaChuang發表於2020-12-29

力扣85-最大矩形

一、原題題目

1.1 題目

  給定一個僅包含 01 、大小為 rows x cols 的二維二進位制矩陣,找出只包含 1 的最大矩形,並返回其面積。

1.2 示例

  • 示例1:

    題目示圖

    輸入: matrix = [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”],[“1”,“0”,“0”,“1”,“0”]]
    輸出: 6
    解釋: 最大矩形如上圖所示。

  • 示例2:

    輸入: matrix = []
    輸出: 0

  • 示例3:

    輸入: matrix = [[“0”]]
    輸出: 0

  • 示例4:

    輸入: matrix = [[“1”]]
    輸出: 1

  • 示例5:

    輸入: matrix = [[“0”,“0”]]
    輸出: 0

提示:

  • row == matrix.length
  • cols == matrix[0].length
  • 0 <= row, cols <= 200
  • matrix[i][j]01

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/maximal-rectangle/

二、解題思路

  • 解題思路

  這個題基於力扣第84題-柱狀圖中最大的矩形可以比較容易的想到思路,我們可以一行一行的考慮最大的矩形,如圖所示。利用上一題的思路還是很容易想到解題思路的。

遞迴執行結果
  • 詳細程式碼(Java)
public int maximalRectangle(char[][] matrix) {
    if(matrix.length == 0|| matrix == null) return 0;   // 當字元二維陣列不存在輸出0
    int[] a = new int[matrix[0].length];        // 記錄每一行中每一個位置向上連續1的個數
    int max = 0;        // 記錄最大的矩形面積,初始化為0
    for (int i = 0;i<matrix.length;i++){        // 遍歷每一行
      for (int j = 0;j<matrix[0].length;j++){ // 統計每一個位置向上連續1的個數
        int count = 0;      // 每一個位置初始化向上連續1的個數為0
        for (int k = i;k>=0;k--){   // 向上遍歷
          if (matrix[k][j]=='1')count++;
          else break;
        }
        a[j] = count;
      }
      max = Math.max(max,largestRectangleArea(a));
    }
    return max;
}
// 第84題-柱狀圖中最大的矩形
public int largestRectangleArea(int[] heights) {
    if (heights == null || heights.length==0)   return 0;   // 陣列為空返回0
    int len = heights.length;       // 記錄長度
    int Smax = 0;                   // 記錄最大面積
    Deque<Integer> stack = new ArrayDeque<>(len);
    for (int i =0;i<len;i++){       // 遍歷每一個元素
      // 棧不為空,且當前元素小於棧頂元素,則計算棧頂元素能勾勒矩形的面積
      while (!stack.isEmpty()&&heights[i]<heights[stack.peekLast()]){
        int right = i;          // 右邊界為當前下標
        int height = heights[stack.pollLast()]; // 棧頂出棧記錄高度
        int left = stack.isEmpty()?-1:stack.peekLast();  // 左邊界:棧不空則為棧頂元素,否則為-1
        Smax = Math.max(Smax,height*(right-left-1));    // 計算面積比較
      }
      stack.addLast(i);   // 棧頂元素不大於當前值,入棧
    }
    while (!stack.isEmpty()){   // 遍歷完了陣列
      int right = len;        // 右邊界為陣列長度
      int height = heights[stack.pollLast()]; // 棧頂出棧記錄高度
      int left = stack.isEmpty()?-1:stack.peekLast(); // 左邊界:棧不空則為棧頂元素,否則為-1
      Smax = Math.max(Smax,height*(right-left-1));    // 計算面積比較
    }
    return Smax;
}
  • 程式碼執行結果
遞迴執行結果

三、總結

  這兩天的題目都是困難,做的很吃力,這個題就先這樣做著吧,後面有精力在分析多方法。

相關文章