zoukankan      html  css  js  c++  java
  • [leetcode] Largest Rectangle in Histogram @ Python [图解] [很难]

    原题地址:https://oj.leetcode.com/problems/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 height = [2,1,5,6,2,3],
    return 10.

    解题思路:又是一道很巧妙的算法题。

    Actually, we can decrease the complexity by using stack to keep track of the height and start indexes. Compare the current height with previous one.

    Case 1: current > previous (top of height stack)
    Push current height and index as candidate rectangle start position.

    Case 2: current = previous
    Ignore.

    Case 3: current < previous
    Need keep popping out previous heights, and compute the candidate rectangle with height and width (current index - previous index). Push the height and index to stacks.

    (Note: it is better use another different example to walk through the steps, and you will understand it better).

    [最优解法] (下面提到的图2是制题目里面的第2个图)

    class Solution:
        # @param height, a list of integer
        # @return an integer
        def largestRectangleArea(self, height):
            #如图2所示,从左到右处理直方,当i = 4 时,小于当前栈顶(即直方i=3),对于直方i=3,无论后面还是前面的直方,都不可能得到比目前栈顶元素更高的高度了,处理掉直方i=3(计算从直方i=3到直方i=4 之间的矩形的面积,然后从栈里弹出);对于直方i=2 也是如此;直到碰到比直方i=4 更矮的直方i=1。这就意味着,可以维护一个递增的栈,每次比较栈顶与当前元素。如果当前元素大于栈顶元素,则入栈,否则合并现有栈,直至栈顶元素小于当前元素
            stack, area, i = [], 0, 0
            height.append(0)
            while i < len(height):
                if stack == [] or height[i] > height[stack[-1]]:
                    stack.append(i)
                    i += 1
                else:
                    curr = stack.pop()
                    width = i if stack == [] else (i - 1) - stack[-1]  #Note; i – 1 resulted from i += 1
                    area = max(area, height[curr] * width)
            return area

    这个是别人的解法,但是过于累赘。

    class Solution:
        # @param height, a list of integer
        # @return an integer
        # @good solution!
        def largestRectangleArea(self, height):
            stack=[]; i=0; area=0
            while i<len(height):
                if stack==[] or height[i]>height[stack[len(stack)-1]]:
                    stack.append(i)
                else:
                    curr=stack.pop()
                    width=i if stack==[] else i-stack[len(stack)-1]-1
                    area=max(area,width*height[curr])
                    i-=1
                i+=1
            while stack!=[]:
                curr=stack.pop()
                width=i if stack==[] else len(height)-stack[len(stack)-1]-1
                area=max(area,width*height[curr])
            return area

    常规解法,所有的面积都算一遍,时间复杂度O(N^2)。不过会TLE。

    class Solution:
        # @param height, a list of integer
        # @return an integer
        # @good solution!
        def largestRectangleArea(self, height):
            maxarea=0
            for i in range(len(height)):
                min = height[i]
                for j in range(i, len(height)):
                    if height[j] < min: min = height[j]
                    if min*(j-i+1) > maxarea: maxarea = min*(j-i+1)
            return maxarea
  • 相关阅读:
    LeetCode 264. Ugly Number II
    LeetCode 231. Power of Two
    LeetCode 263. Ugly Number
    LeetCode 136. Single Number
    LeetCode 69. Sqrt(x)
    LeetCode 66. Plus One
    LeetCode 70. Climbing Stairs
    LeetCode 628. Maximum Product of Three Numbers
    Leetcode 13. Roman to Integer
    大二暑假周进度报告03
  • 原文地址:https://www.cnblogs.com/asrman/p/4001381.html
Copyright © 2011-2022 走看看