n数之和总结
时间:2021-04-19 14:57:12
收藏:0
阅读:0
1.两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
可以按任意顺序返回答案。
做法:hash表,O(n)
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int>mp;
for(int i=0;i<nums.size();i++)
{
int t=target-nums[i];
if(mp.find(t)!=mp.end())
return {i,mp[t]};
mp[nums[i]]=i;
}
return {0,0};
}
};
原题链接
2.三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
原题链接
做法:先排序O(nlogn),第一个数移动,后两个数用two sum的双指针的做法,总时间复杂度O(n * n),由于不可以包含重复的三元组,因此处理完后需要对临近的重复数去掉
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>>result;
int n=nums.size();
sort(nums.begin(),nums.end());
for(int i=0;i<n;i++)
{
//确保i改变了
if(i>0&&nums[i]==nums[i-1]) continue;
int t=-nums[i];
int j=i+1,k=n-1;
while(j<k)
{
if(nums[j]+nums[k]>t) k--;
else if(nums[j]+nums[k]<t) j++;
else
{
vector<int>ans;
ans.push_back({nums[i],nums[j],nums[k]});
result.push_back(ans);
//确保j改变了
while(j<k&&nums[j]==nums[j+1])j++;
//确保k改变了
while(j<k&&nums[k]==nums[k-1])k--;
j++,k--;
}
}
}
return result;
}
};
3.最接近的三数之和
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。
原题链接
同上排序,后双指针,同时跟新最接近这一个性质。
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int n=nums.size();
//先排序
sort(nums.begin(),nums.end());
int closesum=nums[0]+nums[1]+nums[2];
for(int i=0;i<n-2;i++)
{
int l=i+1,k=n-1;
while(l<k)
{
int threesum=nums[i]+nums[l]+nums[k];
if(abs(threesum-target)<abs(closesum-target))
closesum=threesum;
if(threesum>target) k--;
else if(threesum<target) l++;
else
{
return target;
}
}
}
return closesum;
}
};
4.四数之和
给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
注意:答案中不可以包含重复的四元组。
原题链接
类似三数之和,时间复杂度O( n * n * n )
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
int n=nums.size();
sort(nums.begin(),nums.end());
vector<vector<int>>res;
if(n<4) return res;
for(int i=0;i<n-3;i++)
{
//确保nums[a]改变了
if(i>0&&nums[i]==nums[i-1]) continue;
for(int j=i+1;j<n-2;j++)
{
//确保nums[b]改变了
if(j>i+1&&nums[j]==nums[j-1]) continue;
int c=j+1,d=n-1;
while(c<d)
{
if(nums[i]+nums[j]+nums[c]+nums[d]<target) c++;
else if(nums[i]+nums[j]+nums[c]+nums[d]>target) d--;
else
{
res.push_back({nums[i],nums[j],nums[c],nums[d]});
//确保nums[c]改变了
while(c<d&&nums[c]==nums[c+1])c++;
//确保nums[d]改变了
while(c<d&&nums[d]==nums[d-1])d--;
c++,d--;
}
}
}
}
return res;
}
};
评论(0)