leetcode面试题 17.21.——直方图的水量

题目地址

大意:给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为 1。

在这里插入图片描述

一、单调栈解法

使用单调递减的单调栈,按照每层可以接的水做累加。

在这里插入图片描述

假设 : 4 3 2 0 1 5
下标 : 0 1 2 3 4 5
那么按照单调栈,首先入栈4,3,2,0。
下一个值为1,1>0,0出栈,2>1
则2 0 1可以接水,高为min(2-0,1-0),宽为1,接水量为1,此时1入。
下一个值为5,5>1,1出栈,栈顶值为2
则2 1 5 可以接水,高为min(5-1,2-1),宽为2,接水量为2,此时因为2<5,则2出栈,继续计算,栈顶值为3,3 2 5又可以接水,以此类推直到栈顶元素大于5或为空

class Solution {
    
    
public:
	int trap(vector<int>& height) {
    
    
		stack<int > s;
		int water = 0;
		for (int i = 0; i < height.size(); i++)
		{
    
    
			while (!s.empty() && height[i] > height[s.top()])
			{
    
    
				int num = s.top();
				s.pop();
				while (!s.empty() && height[num] == height[s.top()])
					s.pop();
				if (!s.empty())
				{
    
    
					int wid = i - s.top() - 1;
					//宽度
					int he = min(height[i] - height[num], height[s.top()] - height[num]);
					//高度
					water += wid * he;
				}
			}
			s.push(i);
		}
		return water;
	}
};

二、双指针解法

核心思想:左右两个柱子中间能蓄水,决定蓄多少水取决于短的那根柱子。

设置 left,right 双指针,指向直方图首部和尾部,高度设置为leftmax,rightmax。

当leftmax<rightmaxm,则左边的柱子低于右边的柱子,则一个索引(index)下的蓄水量等于 , leftmax - height[index] 。反之左边同理

class Solution {
    
    
public:
	int trap(vector<int>& height) {
    
    
        if(height.size()<3) return 0;
        int left=0,right=height.size()-1;
        int leftmax=height[left],rightmax=height[right];
		int water = 0;
        while(left<right)
        {
    
    
            if(leftmax<rightmax)
            {
    
    
                water+=leftmax-height[left];
                left++;//更新值
                leftmax=max(leftmax,height[left]);
            }
            else
            {
    
    
                water+=rightmax-height[right];
                right--;
                rightmax=max(rightmax,height[right]);
            }
        }
		return water;
	}
};

猜你喜欢

转载自blog.csdn.net/weixin_45605341/article/details/111550131
今日推荐