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