栈学习----接雨水

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;
//    }
//};




 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值