解题思路:先排序再利用双指针思想然后再去重处理。去重要 nums [i] == nums [i- 1 ] 考虑-1,-1,2这种情况。
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(),nums.end());vector<vector<int>>result;for(int i = 0;i<nums.size();i++){if(nums[i] > 0)return result;if(i>0 && nums[i] == nums[i-1])continue;int left = i+1,right = nums.size()-1;while(left < right){if(nums[i]+ nums[left]+nums[right]>0)right--;else if(nums[i]+ nums[left]+nums[right]<0)left++;else{result.push_back(vector<int>{nums[i],nums[left],nums[right]});right--;left++;while(left < right && nums[right] == nums[right+1])right--;while(left<right && nums[left] == nums[left-1])left++;}}}return result;}
};
解题思路:
当前能接住的雨水=min(左侧最高,右侧最高)−当前高度 可以理解为能储水的体积 是哪一侧的最高高度然后减去当前高度
利用双指针不断向中间移动,然后通过动态更新leftmax和rightmax,当左指针最大高度小于右指针最大高度就左移反之就右移。能够存储的雨水量是一侧得到的最大高度减去当前的高度。能存储雨水的一定是短板而不是长板所以长板可以忽略不计。
利用哪一侧高度低哪一侧指针去移动。为什么只比较 leftmax 和 rightmax:
-
如果 leftmax < rightmax,说明左侧的高度限制了雨水量,右侧高度足够高,可以忽略右侧的影响。
-
反之,右侧高度限制了雨水量,忽略左侧的影响。
移动较小的一边是因为:
-
当前柱子的储水量取决于较小的一边。
-
较大的一边还有可能影响后续柱子的储水量,所以暂时不移动。
class Solution { public:int trap(vector<int>& height) {int left = 0,right = height.size()-1,sum = 0;int leftmax=0,rightmax=0;while(left < right){leftmax = max(leftmax,height[left]);rightmax = max(rightmax,height[right]);if(leftmax < rightmax){sum += leftmax-height[left];left++;}else{sum += rightmax-height[right];right--;}}return sum;} };