三数之和
- 1. 题目解析
- 2. 讲解算法原理
- 3. 编写代码
1. 题目解析
题目地址:三数之和
2. 讲解算法原理
- 首先对输入的数组进行排序,以便后续使用双指针法。
- 初始化一个空的二维向量 ret,用于存储结果。
- 使用一个循环遍历数组中的每个元素,假设当前元素为 nums[i]。
- 如果 nums[i] 大于0,则跳出循环,因为排序后的数组中不可能存在三个数之和为0。
- 将 nums[i] 取相反数,记为 temp,即 temp = -nums[i]。
- 初始化两个指针 left 和 right,分别指向 i+1 和数组末尾。
- 在 left < right 的条件下,进行循环:
- 如果 nums[left] + nums[right] < temp,说明和偏小,将 left 右移一位。
如果 nums[left] + nums[right] > temp,说明和偏大,将 right 左移一位。
如果 nums[left] + nums[right] == temp,说明找到了一组解,将 {nums[left], nums[right], nums[i]} 加入到 ret 中。 - 然后将 left 右移一位,right 左移一位,继续寻找下一组解。
- 同时需要进行去重处理,即跳过所有与当前值相同的元素,以防止重复的解。
- 在每次循环结束后,将指针 i 右移一位,继续寻找下一个元素的解。
同样需要进行去重处理,跳过所有与当前值相同的元素。 - 最后返回结果 ret。
3. 编写代码
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ret;
//排序
sort(nums.begin(),nums.end());
int left=0,right=nums.size()-1;
int n=nums.size();
//利用双指针解决
for (int i=0;i<n;)
{
if(nums[i]>0) break;
int temp=-nums[i];
left=i+1;
right=n-1;
while( left<right)
{
if((nums[left]+nums[right])<temp)
left++;
else if((nums[left]+nums[right])>temp)
right--;
else
{
ret.push_back({nums[left],nums[right],nums[i]});
left++;
right--;
//查重,防止越界
while(left<right && nums[left]==nums[left-1])
{
left++;
}
while(left<right && nums[right]==nums[right+1])
{
right--;
}
}
}
i++;
while(i<n && nums[i]==nums[i-1])
{
i++;
}
}
return ret;
}
};