zoukankan      html  css  js  c++  java
  • leetcode Largest Rectangle in Histogram

    直方图上的最大矩形。这道题很有意思。研究了半天才研究出来是个什么意思。

    首先看题目:

    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.

    网上找到一个解法,是用栈来解决。解法思想如下:

    定义两个栈,一个存储矩形的高度,一个存储index,用来计算宽度。

    我们首先分析一种情况,如果对于一个递增的数列,例如{1,2,3,4,5},那么,他的最大值情况很好分析。

    即,1*5,2*4,3*3,4*2,5*1这5种情况,那么最大值显然为9。所以,我们首先考虑,如果遇到递增的子数列,

    我们只需按照上面的方法来处理该递增子数列,即可得到对于这个子数列的最优解。

    因此,如果当前处理的index处于一个递增子数列中,那么只是简单的将index和a[index]分别入栈即可。

    当走到该递增子数列的终点时,即a[i]<a[i-1]时,结算之前的递增子数列。

    此时,重点来了,在结算该递增子数列时,并不要结算ALL,例如,对于1,2,3,4,5,3这一数列来说,当index指向a[5]时,

    开始弹出栈,结算。然而只结算到a[i]>a[5]的那部分,即结算4,5这两个点。为什么?

    因为对于a[i]>a[5]的数来说,a[5]是一个凹陷,采用他们的值作为高度的矩形不会超过a[5]这个点,而这一结论对a[i]<=a[5]

    的部分并不成立,也就是说,对于例子中的a[1],以它的值作为高度的矩形有可能越过a[5]这个点。因此在将这个点记录下来。并且记录它

    往左边的尽头。最后再进行结算。给出代码:

    public class Solution {
    
    	/**
    	 * @param args
    	 */
    
    	// O(n) using two stacks  
    	public int largestRectangleArea(int[] height) {  
    	  // Start typing your Java solution below  
    	  // DO NOT write main() function  
    	  int area = 0;  
    	  java.util.Stack<Integer> heightStack = new java.util.Stack<Integer>();  
    	  java.util.Stack<Integer> indexStack = new java.util.Stack<Integer>();  
    	  for (int i = 0; i < height.length; i++) {  
    		  System.out.println(heightStack);System.out.println(indexStack); 
    	    if (heightStack.empty() || heightStack.peek() <= height[i]) {  
    	      heightStack.push(height[i]);  
    	      indexStack.push(i);  
    	    } else if (heightStack.peek() > height[i]) {  
    	      int j = 0;  
    	      while (!heightStack.empty() && heightStack.peek() > height[i]) {  
    	        j = indexStack.pop();  
    	        int tmp=heightStack.pop();
    	        int currArea = (i - j) * tmp;  
    	        System.out.println("i="+i+",j="+j+"tmp="+tmp);
    	        if (currArea > area) {
    	        	
    	          area = currArea;  
    	        }  
    	      }  
    	      heightStack.push(height[i]);  
    	      indexStack.push(j);  
    	    }  
    	  }  
    	  System.out.println(heightStack);
    	  System.out.println(indexStack);
    	  while (!heightStack.empty()) {  
    	    int currArea = (height.length - indexStack.pop()) * heightStack.pop();  
    	    if (currArea > area) {  
    	      area = currArea;  
    	    }  
    	  }  
    	  return area;  
    	} 
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		int [] nums={1,2,3,4,5,6,3,4,5,2};
    		System.out.println(new Solution().largestRectangleArea(nums));
    	}
    
    }
    

      

  • 相关阅读:
    进程控制(二)
    进程控制(一)
    python的signal
    python的logging模块
    python守护进程
    C语言关键字、标识符和注释
    青春代码
    冒泡排序 js
    数组
    js 运算符
  • 原文地址:https://www.cnblogs.com/elnino/p/5505456.html
Copyright © 2011-2022 走看看