算法面試題——直方圖內最大矩陣

題目:給出一個直方圖(如圖所示),求出所給直方圖中所包含的最大矩陣面積。直方圖可以用一個整數數組表示,如上圖爲[2, 1, 5, 6, 2, 3]。每個直方塊的寬度均爲1。上圖中包含的最大矩陣面積爲10。來源:http://www.jiuzhang.com/problem/43/


解題思路:如果對於每個直方塊,找到從它開始往左邊數第一個比它小的,和往右邊數第一個比他小的,則可以確定出以該直方塊爲最矮一塊的矩陣的最大面積。使用數據結構棧,棧中保存遞增序列,從左到右依次遍歷每個數讓其入棧,入棧之前先pop出所有>=該數的數,從而保持棧中的遞增序列。pop完之後的棧頂元素即爲該數往左邊數第一個比他小的數。同理反過來遍歷一次可以得到往右邊數第一個比他小的數。時間複雜度O(n),空間複雜度O(n)。


代碼實現:

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class Rectangle {
	
	private int index;
	private int height;
	private int left;
	private int right;
	
	@Override
	public String toString() {
		return "Rectangle [height=" + height + ", index=" + index + ", left="
				+ left + ", right=" + right + "]";
	}

	protected static int getMaxRectangle(List<Rectangle> lists){
		
		Stack<Rectangle> stack = new Stack<Rectangle>();
		
		//輸入檢測
		if(lists == null || lists.size() == 0){
			System.out.println("非法輸入!");
			System.exit(0);
		}
		
		//從左往右入棧
		for(int i = 0; i < lists.size(); i++){
			
			Rectangle rectangle = lists.get(i);
					
			while(!stack.isEmpty() && stack.peek().height >= lists.get(i).height){
				stack.pop();
			}						
			
			if(stack.isEmpty()){
				rectangle.left = 0;
			}else {
				rectangle.left = stack.peek().index;
			}
			
			lists.set(i, rectangle);
			
			stack.push(rectangle);
		}
		
		stack.clear();
		
		//從右往左入棧
		for(int i = lists.size() - 1; i >= 0; i--){
			
			Rectangle rectangle = lists.get(i);
			
			while(!stack.isEmpty() && stack.peek().height >= lists.get(i).height){
					stack.pop();
			}	
			
			if(stack.isEmpty()){
				rectangle.right = lists.size() + 1;
			}else {
				rectangle.right = stack.peek().index;
			}
			
			lists.set(i, rectangle);
			
			stack.push(rectangle);
		}
		
		//計算面積最大值
		int max = (lists.get(0).right - lists.get(0).left - 1)*lists.get(0).height;
		System.out.println(lists.get(0));
		
		for(int i = 1; i < lists.size(); i++){
			int temp = (lists.get(i).right - lists.get(i).left - 1)*lists.get(i).height;
			System.out.println(lists.get(i));
			if(max < temp){
				max = temp;
			}
		}
		
		return max;
	}


	public static void main(String[] args) {
		
		int [] values = new int[]{2, 1, 5, 6, 2, 3};

		List<Rectangle> lists = new ArrayList<Rectangle>();
		
		for (int i = 0; i < values.length; i++) {
			Rectangle rectangle = new Rectangle();
			rectangle.height = values[i];
			rectangle.index = i + 1;
			lists.add(rectangle);
		}
		
		System.out.println(Rectangle.getMaxRectangle(lists));		
	}

}


運算結果:




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章