Leetcode-42-接雨水(栈解)

题目描述 题目来源:力扣
定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
Leetcode-42-接雨水(栈解)_第1张图片
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

示例:

输入: [0,1,0,2,1,0,1,3,2,1,2,1]

输出: 6


思路分析
接雨水:第一种解法,点此了解
之前用了一种普通解法解决,后来正式运用栈,发现没有一点知识储备是一件麻烦的事情。为什么这么说呢,因为要用到一种单调栈,这个栈的作用简单说来就是按从大到小或从小到大的顺序讲一下数据存储下来,最关键的一点与排序不同的是:这是部分数据元素。比如3 2 4 8这四个数,开始进入3 ,然后是 2,到 4 的时候,由于4大于栈顶元素 2 即将2Pop出来,然后 3 也小于 4 ,将3 也Pop出来,再把 4 放入,后面的依次操作即可,最后的栈的情况是只有 8在里面;我说的很省略,腾讯云单调栈及其应用讲解,点击了解。那么针对这一道题来说,我们就将利用单调栈的这个性质进行实现。
具体的实现思路是这样的:
我们利用栈单调性,如果栈中的元素是[ 3 1 0]然后下一个元素是2,那么我们就可以知道前面很可能是有一个坑的,将 0 Pop出来之后,并且0作为bottom的高,那么计算该处的水的量即:找到两边极小值(在1 0 2)中,是 1,那么可容水量即为 ( 2 - 1 )* (1 - 0 ) = 1,后面依次计算机即可。


代码如下c++

/*
 Name: 接雨水 
 Author: 德林恩宝 
 Date: 05/10/19 15:17
 Description: 如代码 
*/
#include
#include
using namespace std;
#define Maxsize 1000
stack<int> stak;
int Function(int num[ ],int n)
{
	int i,sum = 0;
	for(i = 0;i < n;i++)
	{
		int width = 0;//宽度初始化 
		while( !stak.empty() && num[ stak.top() ] < num[i])//如果栈非空并且满足栈顶元素小于即将进入的元素 
		{
			int temp = stak.top();//获得栈顶元素 
			stak.pop();//出栈 
			if( stak.empty() )//为空时 
				break;
			if( num[temp] == num[ stak.top() ] )//相等时 
				continue;
			width = i - stak.top() - 1;//宽度计算 
			int height = min(num[i],num[ stak.top() ]);//最小高度 
			sum += width * ( height - num[temp] );//容量累计 
		}
		stak.push( i );//入栈 
	}
return sum;//返回值 
}
int main()
{
	int num[Maxsize],i = 0,n;
	cout << "请输入柱子数量" << endl;
	cin>>n;
	for(i = 0;i < n;i++)
		cin>>num[i];
	cout << "一共可以存储的最大容量为" <<Function(num,n)<<endl;
	return 0;  
} 

运行结果
Leetcode-42-接雨水(栈解)_第2张图片


c++中的stack栈的运用,其实蛮不错的。
涉及到的各部分函数简介:
声明:stack stak;
push() 函数:将 val 值压栈,使其成为栈顶的第一个元素;
Pop()函数:删除栈顶元素,但不返回;
top()函数:返回栈顶元素但不删除;
empty()函数:判断是否为空;

你可能感兴趣的:(#,exercise,#,算法题)