class Solution {
public:
int trap(vector<int>& height)
{
if(height.size() == 0) //height为空时返回0
return 0;
int res = 0; //所接雨水的单位数
vector<int>::iterator max = max_element(height.begin(),height.end()); //找到当前vector中的最高位置
left(height,res,max); //从最高处向左遍历
right(height,res,max); //从最高处向右遍历
return res;
}
void left(vector<int> & v,int &res,vector<int>::iterator m)
{
if(m != v.begin()) //迭代器所返回的还没到最左端
{
int m_pos = m - v.begin(); //记录下当前右端的下标
vector<int>::iterator max_left = max_element(v.begin(),m); //找到当前左端的最高高度
int ml_pos = max_left - v.begin(); //记录当前最高左端的下标
for(int i = ml_pos;i < m_pos;i++) //循环计算此时构成容器所接的雨水数目
{
res += *max_left - v[i];
}
left(v,res,max_left); //将当前的左端最高高度置为最高高度
}
return;
}
void right(vector<int> &v,int &res,vector<int>::iterator m) //思维同上
{
vector<int>::iterator temp = m;
temp++;
if(temp != v.end())
{
int m_pos = m - v.begin();
vector<int>::iterator max_right = max_element(temp,v.end());
int mr_pos = max_right - v.begin();
for(int i = m_pos;i < mr_pos;i++)
{
if(v[i] < *max_right)
{
res += *max_right - v[i];
}
}
right(v,res,max_right);
}
return;
}
};
算法思路:
都在注释里了。大致就是先找到最高高度,然后找到左边最高高度,计算两个下标之间能接的雨水数目,再将左边最高高度当成剩余左边的最高高度,迭代。右边也一样。
大佬们算法的学习:
暴力求解的内存第一算法:
除了第一个和最后一个不需要计算雨量,然后对每一个都寻找左边最大值以及右边最大值,然后单独计算每个的储雨量,最后求和。
ps:
中间想了个错误的方法,主要是完全按照案例1去写的,测试第二个案例的时候发现不对才意识到思维方法有问题。
以下为当时想的错误答案:
//class Solution {
//public:
// int trap(vector<int>& height)
// {
// if (height.size() == 0)
// return 0;
// vector<int> left; //存储左边的高度
// vector<int> right; //存储右边的高度
// left.push_back(height[0]); //先将height[0]压入左边
// int maxrightlen = 0; //右边最高的高度先置为0
// int maxleftlen = height[0]; //左边最高的高度先置为height[0];
// int res = 0; //res为所接的雨水单位数
// int minlen = maxleftlen; //单个雨水容器的最高先定为左边最高的高度
// bool flag = height[1] > height[0] ? true : false; //用于判断是接雨水的左边还是右边,左边为true;
// for (int i = 1; i < height.size(); i++) //遍历整个height数组
// {
// if (flag == true) //true表示当前还在探索容器的左边
// {
// if (height[i] > height[i - 1]) //当前位置的高度比上一个大的时候,说明已经开始进入容器的右端
// {
// flag = false; //容器开始进入右端时flag置为false;
// i--; //i--用于下一次右端的压入,不然会少一个数据
// continue;
// }
// else
// {
// if (height[i] > maxleftlen) //容器还在左端时,若当前高度高于左端最高的高度,则将左端最高高度更新
// {
// maxleftlen = height[i];
// }
//
// left.push_back(height[i]); //将当前左端更新
// }
// }
// if (flag == false) //false表示当前还在探索容器的右边
// {
// if (height[i] < height[i - 1]) //当前位置的高度比上一个小的时候,说明已经开始进入下一个容器的左端的第二个,开始计算当前容器装雨水的单位数
// {
// minlen = maxleftlen > maxrightlen ? maxrightlen : maxleftlen; //容器单位数是由两端最低决定的
// for (int j = 0; j < left.size(); j++)
// {
// if (minlen > left[j])
// {
// res += minlen - left[j];
// }
// }
// for (int j = 0; j < right.size(); j++)
// {
// if (minlen > right[j])
// {
// res += minlen - right[j];
// }
// } //当前容器装水数计算完毕
// left.clear();
// right.clear();
// flag = true;
// maxleftlen = height[i - 1];
// maxrightlen = 0;
// i--;
// continue;
// }
// else
// {
// if (height[i] > maxrightlen)
// maxrightlen = height[i];
// right.push_back(height[i]);
// }
// }
// }
// return res;
// }
//};