三数之和

LeetCode三数之和&最接近三数之和_重复元素


1、向量中不足3个元素时,返回空向量

2、排序后最小元素大于0或最大元素小于0,返回空向量

3、游标 i 移动时,若nums[i] > 0,直接跳出循环。因为在有序数组中,nums[i]比nums[low]和nums[high]都小。

4、无论三数之和是否等于0,如不加以判断,跳过重复元素,则会超时

#include<iostream>
#include<vector>
#include<set>

using namespace std;

vector<vector<int>> threeSum(vector<int>& nums) {
set<vector<int>> res;
int n = nums.size();
//检验1:总共没有3个元素,返回空向量
if(nums.size() < 3){
return vector<vector<int>>();
}
sort(nums.begin(), nums.end(), less<int>());//升序
//检验2:最小的数大于0或最大的数小于0,无法使得三数之和为0
if(nums[0] > 0 || nums[n - 1] < 0){
return vector<vector<int>>();
}
for(int i = 0; i < n - 2; i++){
//检验3:当前值大于0,而后面的nums[low]和nums[high]都比nums[i]大,不可能使得三数之和为0,直接退出
if(nums[i] > 0){
break;
}
int target = 0 - nums[i];
int low = i + 1;
int high = n - 1;

while(low < high){
if(nums[low] + nums[high] < target){
low++;
//跳过重复元素时,切忌索引超过有效范围
while(nums[low] == nums[low-1] && low < high){
low++;//跳过重复元素
}
}else if(nums[low] + nums[high] > target){
high--;
while(nums[high] == nums[high+1] && high > low){
high--;
}
}else{
vector<int> temp;
temp.push_back(nums[i]);
temp.push_back(nums[low]);
temp.push_back(nums[high]);
res.insert(temp);
low++;
while(nums[low] == nums[low-1] && low < high){
low++;
}
high--;
while(nums[high] == nums[high+1] && high > low){
high--;
}
}
}
}
return vector<vector<int>>(res.begin(), res.end());
}

int main(){
int num[] = {-2, 0, 1, 1, 2};
vector<int> nums(num, num+5);
vector<vector<int> > ans = threeSum(nums);
for ( vector<vector<int> >::iterator it=ans.begin(); it!=ans.end(); it++ ) {
cout<<"[";
for(int i=0; i<(*it).size(); i++)
cout << (*it)[i] << " ";
cout<<"]"<<endl;
}
return 0;
}

LeetCode三数之和&最接近三数之和_重复元素_02

最接近三数之和

LeetCode三数之和&最接近三数之和_#include_03

/*
sort函数是c++中标准模板库的的函数,在qsort()上已经进行了优化,
根据情况的不同可以采用不同的算法,所以较快。
在同样的元素较多和同样的比较条件下,sort()的执行速度都比qsort()要快。
另外,sort()是类属函数,可以用于比较任何容器,任何元素,任何条件。
使用时需调用<algorithm>
sort(begin(), end(), cmp)
*/
#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int low;
int high;
long sum = INT_MAX;
for(int i=0; i<=nums.size()-3; i++){
low = i + 1;
high = nums.size()-1;
while(low < high){
long temp = nums[low] + nums[i] + nums[high];
sum = abs(sum-target)>abs(temp-target) ? temp : sum;
if(temp > target){
int value = nums[high];
//为了缩短计算时间,跳过重复元素
while(low < high && nums[high] == value){
high--;
}
}
else if(temp < target){
int value = nums[low];
while(low < high && nums[low] == value){
low++;
}
}
//sum == target
else
return sum;
}
}
return sum;
}

int main(){
vector<int> nums;
nums.push_back(-1);
nums.push_back(2);
nums.push_back(1);
nums.push_back(4);
int target = 1;
cout<<threeSumClosest(nums, target)<<endl;
}

LeetCode三数之和&最接近三数之和_i++_04