day49-mono stack-part2-8.20

tasks for today:

1. 42.接雨水

2. 84.柱状图中最大矩形

----------------------------------------------------------------------

1. 42.接雨水

method 1: finding the right max and left max of each element, chose the min(rightmax, leftmax), then deduct the element height would be the water for each element.

In this code, the left-firstbigger and right-firstbigger list are derived, and then the left-max and right-max list are derived based on those. and then calculate the held water one by one.

class Solution:
    def trap(self, height: List[int]) -> int:
        if len(height) <= 2: return 0

        rightBigger = self.findBigger(height)
        leftBigger = self.findBigger(list(reversed(height)))

        # print(rightBigger)
        # print(list(reversed(leftBigger)))

        for i in range(len(height)):
            if rightBigger[i] != -1:
                rightBigger[i] = max(rightBigger[i:])
            if leftBigger[i] != -1:
                leftBigger[i] = max(leftBigger[i:])
        
        leftBigger = list(reversed(leftBigger))

        # print(rightBigger)
        # print(leftBigger)

        volume = 0
        # result = []

        for i in range(len(height)):
            # result.append(max(min(leftBigger[i], rightBigger[i]) - height[i], 0))
            volume += max(min(leftBigger[i], rightBigger[i]) - height[i], 0)
        
        # print(result)
        
        return volume
    # noted: this function find the first bigger one in right hand side, instead of the biggest one
    def findBigger(self, nums):
        result = [-1] * len(nums)
        monStack = [0]

        for i in range(1, len(nums)):
            if nums[i] <= nums[monStack[-1]]:
                monStack.append(i)
            else:
                while len(monStack) != 0 and nums[i] > nums[monStack[-1]]:
                    eleInd = monStack.pop()
                    result[eleInd] = nums[i]
                monStack.append(i)
        
        return result

method 2: this is simlified, bacause the held water is calculated along with the process of monoStack.

class Solution:
    def trap(self, height: List[int]) -> int:
        if len(height) <= 2: return 0
        nums = copy.deepcopy(height)
        monStack = [0]
        volume = 0

        for i in range(1, len(nums)):
            if nums[i] < nums[monStack[-1]]:
                monStack.append(i)
            elif nums[i] == nums[monStack[-1]]:
                monStack.pop()
                monStack.append(i)
            else:
                while len(monStack) != 0 and nums[i] > nums[monStack[-1]]:
                    eleInd = monStack.pop()
                    Curstep = height[eleInd]
                    if monStack:
                        Curheight = min(nums[monStack[-1]], nums[i]) - Curstep
                        width = i - monStack[-1] - 1
                        volume += width * Curheight
                monStack.append(i)
        
        return volume

Note: the method 1's essense is calculatiing all the held water by traversing each vertical volume, while the method 2' essense is calculating all the held water by traversing each horizontal volume.

Therefore, the method 1 does not require width calculation, while method 2 requires width calculation.

2. 84.柱状图中最大矩形

This practice is a reverse version of the practice 42, which is reflected by the sequence of the index's represented value in heights. In this practice, the order in monoStack should be descending from top of stack to the bottom of the stack. 

The main strcuture for this code snippet is the same with the method 2 in practice 42, which is calculating vertical volumn, but in this practice, it is not the addition that is wanted, instead, the max is wanted.

Be noted that, in this practice, how to handle the bound is different from the practice 42, which requires complement in both side of the height list with a zero as a place holder, for more convinently dealing with the both sides' bars, which may potentially be a max size area candidate.

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        if len(heights) == 1: return heights[0]
        
        heights.insert(0, 0)
        heights.append(0)

        monoStack = [0]
        result = 0

        for i in range(1, len(heights)):
            if heights[i] > heights[monoStack[-1]]:
                monoStack.append(i)
            elif heights[i] == heights[monoStack[-1]]:
                monoStack.pop()
                monoStack.append(i)
            else:
                while monoStack and heights[i] < heights[monoStack[-1]]:
                    eleInd = monoStack.pop()
                    curstep = heights[eleInd]
                    if monoStack:
                        left = monoStack[-1]
                        right = i
                        width = right - left - 1
                        result = max(result, width * curstep)
                monoStack.append(i)
            
        return result

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值