- 三数之和为0
class Solution {
public:
//双指针法
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
if(nums.size()<3) return res;
int left,right=nums.size()-1;
sort(nums.begin(),nums.end());
//int mp[10000010]={0};
for(int i=0;i<nums.size()-2;i++){
if(nums[i]>0||nums[right]<0) break;
if(i!=0&&nums[i]==nums[i-1]) continue;
left=i+1;
right=nums.size()-1;
while(left<right){
if(nums[i]+nums[left]+nums[right]==0){
vector<int> tri{nums[i],nums[left],nums[right]};
res.push_back(tri);
int dup1=nums[left];
int dup2=nums[right];
while(left<right&&dup1==nums[left]) left++;
while(left<right&&dup2==nums[right]) right--;
}else if(nums[i]+nums[left]+nums[right]>0){
int dup=nums[right];
while(left<right&&nums[right]==dup) right--;
}else{
int dup=nums[left];
while(left<right&&nums[left]==dup) left++;
}
}
}
return res;
}
};
- 最接近target的三数之和
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum-closest
思想
与两数之和排序利用双指针的思想类似。
- 选取left=i+!,right=numsSize-1,计算sum=nums[i]+nums[left]+nums[right],
若sum与target距离要小于minSum与target的距离,则更新minSum。 - 更新left或right,若sum<target则则left++,若sum>target,则right–,sum==target则返回sum。
重复1,2步骤直至left==right
i从0到numsSize-3遍历
代码
int partition(int *nums,int left,int right){
int q=nums[left];
while(left<right){
while(left<right&&nums[right]>=q)
right--;
nums[left]=nums[right];
while(left<right&&nums[left]<=q)
left++;
nums[right]=nums[left];
}
nums[left]=q;
return left;
}
void quickSort(int * nums,int left,int right){
if(left<right){
int pivot=partition(nums,left,right);
quickSort(nums,left,pivot-1);
quickSort(nums,pivot+1,right);
}
}
int cmp(const void *value1, const void *value2)
{
return *(int*)value1 - *(int*)value2;
}
int threeSumClosest(int* nums, int numsSize, int target){
if(numsSize<3) return 0;
int minSum=0x3fff,left,right,sum=0;
// quickSort(nums,0,numsSize-1);
qsort(nums,numsSize,sizeof(nums[0]),cmp);
for(int i=0;i<numsSize-2;i++){
//if(i!=0&&nums[i]==nums[i-1]) continue;
left=i+1;right=numsSize-1;
while(left<right){
sum=nums[left]+nums[right]+nums[i];
if(abs(sum-target)<abs(minSum-target)){
minSum=sum;
}
if(sum>target){
right--;
}else if(sum<target){
left++;
}else
return minSum;
}
}
return minSum;
}