• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
MKT-porter
博客园    首页    新随笔    联系   管理    订阅  订阅
reLeetCode 热题 100- 42 接雨水

image

 

image

 

class Solution {
public:

   /*
    关键  
    左边界  height[zuo]>height[zuo+1]
    右边界  1 是否比height[you]》height[zuo] break;
            2  不是最后一个 height[you]>height[you-1]  &&  height[you]>height[you+1] 
            3 最后一个  height[you]>height[you-1] 
   */

    // 1 失败 找右侧边界 忽略了第一个比自己大的
    int trap1(vector<int>& height) {

        int left =0;
        int right =2;
        int current=1;

        int current_i=0;
        int current_i_cut=0;
        int current_all=0;

        for(int i=1;i<(height.size()-1);++i){

           cout<< i << "  "<< " left "<< left << "  right  "<<right<<"  current_all "<< current_all<<endl;
           current=i;
           if(height[left]>height[left+1]){

              right=current+1;
              bool findright=0;
              if(right==(height.size()-1)){ // 最后一个右边界
               findright=1;
              }
              
              if(height[current]<height[right] && height[right] > height[right+1] && (right+1)<height.size()){ // 正常内部的右边界
                findright=1;
              }
              if(findright==1){
                // 找到右边界
                current_i_cut=0;
                for(int j = left+1;j<right;j++) {
                     current_i_cut=current_i_cut+height[j];
                }
                current_i= min(height[left],height[right])*(right-left-1);
                current_all=current_all+current_i-current_i_cut;
                
                cout<<"i "<< i << "找到到右边界  "
                << " left "<< left << " / "<<height[left]
                << "  right  "<<right << " / "<<height[right]
                << " w = "<< (right-left-1) 
                << " h = "<<  min(height[left],height[right]) 
                << " current_i_cut  "<< current_i_cut 
                << " current_i  "<< current_i 
                << " current_all "<< current_all
                <<endl;
                
                current_i_cut=0;
                current_i=0;
                left=right;
                i=left;

                // cout<<"i "<< i << "找到到右边界 更新数据  "
                // << " left "<< left << " / "<<height[left]
                // << "  right  "<<right << " / "<<height[right]
                // << " w = "<< (right-left-1) 
                // << " h = "<<  min(height[left],height[right]) 
                // << " current_i_cut  "<< current_i_cut 
                // << " current_i  "<< current_i 
                // << " current_all "<< current_all
                // <<endl;
              }
              else{
                  //current_i_cut=current_i_cut+height[i];

                 // cout<<" 减去i " << i << "  数值 "<< height[i]<<endl;

              }

           }
           else{
              current_i_cut=0;
              left=i;     
           }


                // cout<<"i "<< i << "...最后统计 "
                // << " left "<< left << " / "<<height[left]
                // << "  right  "<<right << " / "<<height[right]
                // << " w = "<< (right-left-1) 
                // << " h = "<<  min(height[left],height[right]) 
                // << " current_i_cut  "<< current_i_cut 
                // << " current_i  "<< current_i 
                // << " current_all "<< current_all
                // <<endl;

        }
        
        return current_all;

    }

   // 2 通过但是超时
    int trap2(vector<int>& height) {

        int left =0;
        int right =2;
        int current=1;

        int current_i=0;
        int current_i_cut=0;
        int current_all=0;

        for(int i=1;i<(height.size()-1);++i){


           current=i;
           if(height[left]>height[left+1]){

                int right=left;
                int max_num=0;
                int max_index=0;

                for(int j=left+1;j<height.size();j++){
                    if(height[j]>max_num){
                         max_num=height[j];
                         right=j;
                         if(max_num>height[left])break; // 只需要找到第一个大的
                    }
                }
                         
                
               
                current_i_cut=0;
                int w=right-left-1;
                int h=min(height[right],height[left]);
                

                for(int k=left+1;k<right;k++){
                    current_i_cut=current_i_cut+height[k];
                }

                current_i=w*h;
                current_all=current_all+current_i-current_i_cut;


            //  cout<<"i "<< i << "找到到右边界 更新数据  "
            //     << " left "<< left << " / "<<height[left]
            //     << "  right  "<<right << " / "<<height[right]
            //     << " w = "<< (right-left-1) 
            //     << " h = "<<  min(height[left],height[right]) 
            //     << " current_i_cut  "<< current_i_cut 
            //     << " current_i  "<< current_i 
            //     << " current_all "<< current_all
            //     <<endl;

                left=right;
                i=left;
                

                
         
           }
           else{
              
              left=i;     
           }


        }
        
        return current_all;

    }
    // 双指针通过 参考网友思路 官方费解
    int trap2_shuangzhizhen(vector<int>& height) {
        /*
        关于双指针解法,我使用直接比较lmax与rmax的解法,可以AC。我思考了一下,有一个说明其正确性的解释:
由于两个指针都走过了各自的区域,即left指针左边已经遍历,right指针右边已经遍历,因此可以保证lmax和rmax是各自遍历区域内的最大值。因此较小者一定是对应指针所在位置接水时的较低端。
举例说明即:
考虑有lmax<=rmax,此时无论left到right之间的数有多大,left指针位置能接到多少水由lmax决定,因此此时直接统计该位置对答案的贡献是正确的。当lmax>rmax的情况也同理。
        
        */

        int right=0;
        int left=height.size()-1;
        int right_max,left_max=0;

        int all_water=0;
        while(right<left){
                // 当前位置的水 由左右两侧区间的最短边决定。只要找到两侧谁是最短,就可以先决定一侧。
                right_max=max(right_max,height[right]);// 0-right 区间最大
                left_max=max(left_max,height[left]); // left-N 区间最大
                // right -  left 区间目前未知,但是左右两侧的最小边,决定了对应左右两侧位置的最小边
                
                if(right_max<left_max){ // 右侧最大小于左侧最大
                   // 右侧可以确定,(右侧到左侧中间无论什么情况,左侧最大兜底,右侧不可能在大了)
                    int curent_water=right_max-height[right];  
                    all_water=all_water+  curent_water;
                  //等效all_water += right_max-height[right]
                    right++;
                }
                else{
                    // 左侧可以确定,(右侧到左侧中间无论什么情况,右侧最大兜底,左侧不可能在大了
                    int curent_water=left_max-height[left];  
                    all_water=all_water+  curent_water;
                    left--;
                }
        }

        return all_water;

    }

       int trap(vector<int>& height) {


        int right=0;
        int left=height.size()-1;
        int right_max,left_max=0;

        int all_water=0;
        while(right<left){
                right_max=max(right_max,height[right]);
                left_max=max(left_max,height[left]);
                if(right_max<left_max){
                    int curent_water=right_max-height[right];  
                    all_water=all_water+  curent_water;
                    right++;
                }
                else{
                    int curent_water=left_max-height[left];  
                    all_water=all_water+  curent_water;
                    left--;
                }
        }

        return all_water;

    }

};

  

posted on 2025-09-28 17:30  MKT-porter  阅读(5)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3