题目:15. 三数之和
思路:双指针+排序。先对数组升序排序,然后遍历第一个元素,后面两个元素通过双指针的方式来查找,时间复杂度为0(n^2),细节看注释。
C++版本:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
//对数组升序排序
sort(nums.begin(),nums.end());
//答案
vector<vector<int>> v;
int n=nums.size();
//i是第一个元素的下标
for(int i=0;i<n-2;i++){
//避免重复的三元组
if(i&&nums[i]==nums[i-1]) continue;
//剪枝
if(nums[i]>0) continue;
//后面两个元素的下标
int l=i+1,r=n-1;
while(l<r){
if(nums[i]+nums[l]+nums[r]<0){
l++;
}else if(nums[i]+nums[l]+nums[r]>0){
r--;
}else{
v.push_back({nums[i],nums[l],nums[r]});
l++,r--;
//避免重复的三元组
for(;l<r&&nums[l]==nums[l-1];l++);
for(;r>l&&nums[r]==nums[r+1];r--);
}
}
}
return v;
}
};
JAVA版本:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
//对数组升序排序
Arrays.sort(nums);
//答案
List<List<Integer>> v=new ArrayList<>();
int n=nums.length;
//i是第一个元素的下标
for(int i=0;i<n-2;i++){
//避免重复的三元组
if(i>0&&nums[i]==nums[i-1]) continue;
//剪枝
if(nums[i]>0) continue;
//后面两个元素的下标
int l=i+1,r=n-1;
while(l<r){
if(nums[i]+nums[l]+nums[r]<0){
l++;
}else if(nums[i]+nums[l]+nums[r]>0){
r--;
}else{
List<Integer> tmp=new ArrayList<Integer>();
tmp.add(nums[i]);
tmp.add(nums[l]);
tmp.add(nums[r]);
v.add(tmp);
l++;
r--;
//避免重复的三元组
for(;l<r&&nums[l]==nums[l-1];l++);
for(;r>l&&nums[r]==nums[r+1];r--);
}
}
}
return v;
}
}