双指针
2025/5/18大约 2 分钟
双指针
Leetcode Hot100第二个小专题,前两道为移动零以及盛水最多的容器,暂时未记笔记.
三数之和
力扣题目连接:三数之和
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
代码:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end()); //排序之后
set<vector<int>> result; //使用set方便去重
for(int i=0;i<nums.size()-2;i++){
if(nums[i]>0){ //因为nums[i]值大于0,由于排序,其后面的两个值一定大于等于nums [i],三者相加一定不为0;那么nums[i]后面的值也同理,直接结束循环即可
break;
}
if(i>0&&nums[i]==nums[i-1]){
continue;
}
int l=i+1;
int r=nums.size()-1;//定义双指针
while(l<r){
if(nums[i]+nums[l]+nums[r]<0){
l++;
}
else if(nums[i]+nums[l]+nums[r]>0){
r--;
}
else{
result.insert({nums[i],nums[l],nums[r]});
l++;
r--;
}
}
}
vector<vector<int>> ans(result.begin(),result.end());
return ans;
}
};
接雨水 ⭐⭐⭐⭐⭐困难题目 着重理解
力扣题目连接:接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
[](https://imgse.com/i/pEvcCxx)
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5]
输出:9
代码:
class Solution {
public:
int trap(vector<int>& height) {
int result=0;
int left=0;
int right=height.size()-1;
int leftMax,rightMax=0;
while(left<right){
leftMax=max(height[left],leftMax);//因为leftMax是由height[left]更新过来的,所以在当前这个循环,leftMax一定>=height[left]
rightMax=max(height[right],rightMax);//同理,rightMax一定>=height[right];
if(height[left]<height[right]){ //那么这个时候height[left]一定<=leftMax和rightMax,所以更新left
result+=min(leftMax,rightMax)-height[left];
left++;
}
else{ //同理,此时更新right
result+=min(leftMax,rightMax)-height[right];
right--;
}
}
return result;
}
};