1. 程式人生 > >leetCode 85.Maximal Rectangle (最大矩陣) 解題思路和方法

leetCode 85.Maximal Rectangle (最大矩陣) 解題思路和方法

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

思路:此題的意思是給一個為0或1的矩陣,求全部為1組成的最大矩陣的面積。

此題可以巧妙轉化為求最大直方圖面積的問題。

public class Solution {
    //其思想是將每一列的1逐行相加,遇0為0,遇1相加
    //然後轉化為求每一行的最大直方圖面積的求解
    //最後求出最大全為1的矩形面積
    public int maximalRectangle(char[][] matrix) {
    	//邊界條件
    	if(matrix.length == 0 || matrix[0].length == 0){
    		return 0;
    	}
    	
    	/**
    	 * 按列將每列的1逐行相加
    	 */
        for(int j = 0; j < matrix[0].length; j++){
            for(int i = 1; i < matrix.length; i++){
                if(matrix[i][j] != '0'){//不是0才相加,是0不管
                	matrix[i][j] = (char) (matrix[i-1][j] + 1);
                }
            }
        }
        int maxArea = 0;//最大矩形面積
        for(int i= 0; i < matrix.length; i++){
            maxArea = max(matrix[i],maxArea);//迴圈求最大
        }
        return maxArea;
    }
    
    /**
     * 根據每行,求最大直方圖的面積
     * @param height char陣列
     * @param maxArea 當前最大面積
     * @return
     */
    private int max(char[] height,int maxArea){
        if(height.length == 0){//為空直接返回
            return maxArea;
        }
        /**
         * 兩個棧,分別存在高度和索引
         */
        Stack<Character> stHeight = new Stack<Character>();
        Stack<Integer> stIndex = new Stack<Integer>();
        /**
         * 遍歷
         */
        for(int i = 0 ; i < height.length; i++){
        	//棧為空,或者高度比棧頂高度大,入棧
            if(stHeight.isEmpty() || height[i] > stHeight.peek()){
                stHeight.push(height[i]);
                stIndex.push(i);
            }else if(height[i] < stHeight.peek()){//高度比棧頂高度小
                int lastIndex = 0;//最後的索引值
                while(!(stHeight.isEmpty()) && height[i] < stHeight.peek()){
                    lastIndex = stIndex.pop();
                    int area = (stHeight.pop() - '0')*(i - lastIndex);//計算面積
                    maxArea = maxArea < area ? area:maxArea;
                }
                stHeight.push(height[i]);//當前值入棧
                stIndex.push(lastIndex);//最小索引入棧
            }
        }
        //如果棧不為空,繼續計算
        while(!(stHeight.isEmpty())){
            int area = (stHeight.pop() - '0')*(height.length - stIndex.pop());
            maxArea = maxArea < area ? area:maxArea;
        }
        return maxArea;
    }
}

具體程式碼和思路如下: