0
点赞
收藏
分享

微信扫一扫

两数之和、三数之和(排序+双指针)


文章目录

  • ​​一、和为s的两个数字​​
  • ​​二、两数之和​​
  • ​​三、三数之和​​
  • ​​四、最接近的三数之和​​

一、和为s的两个数字

两数之和、三数之和(排序+双指针)_leetcode


​​和为s的两个数字​​

升序,使用双指针遍历即可

class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int l = 0;
int r = nums.size() - 1;
while(l < r){
if(nums[l] + nums[r] == target){
return {nums[l], nums[r]};
}else if(nums[l] + nums[r] > target){
r--;
}else{
l++;
}
}
return {};
}
};

二、两数之和

两数之和、三数之和(排序+双指针)_while循环_02


​​两数之和​​

用和哈希表存储已经遍历过且没找到和为target的数,key为值,value为元素下标

用target减去当前遍历的数,在哈希表中查找,查找到就可以返回当前下标(i)和从哈希表取出的下标(target - nums[i])。没找到就在哈希表保存当前元素值以及下标

class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> mp; // mp[val] = index
for(int i = 0; i < nums.size(); i++){
if (mp.find(target - nums[i]) != mp.end()){
return {i, mp[target - nums[i]]};
}else{
mp[nums[i]] = i;
}
}
return {};
}
};

三、三数之和

两数之和、三数之和(排序+双指针)_双指针_03


用排序+双指针的方法,时间复杂度为

class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end(), less<int>());
set<vector<int>> ans;

for(int l = 0; l < (int)nums.size() - 2 && nums[l] <= 0; l++){
int mid = l + 1;
int r = nums.size() - 1;
while(mid < r){
int sum = nums[l] + nums[mid] + nums[r];
if(sum == 0){
ans.insert({nums[l], nums[mid], nums[r]});
r--;
while (mid < r && nums[r] == nums[r + 1]) r--; // while循环用于去重
mid++;
while (mid < r && nums[mid] == nums[mid - 1]) mid++; // while循环用于去重
}else if(sum > 0){
r--;
while (mid < r && nums[r] == nums[r + 1]) r--; // while循环用于去重
}else{
mid++;
while (mid < r && nums[mid] == nums[mid - 1]) mid++; // while循环用于去重
}
}
}
return vector<vector<int>> (ans.begin(), ans.end());
}
};

两数之和、三数之和(排序+双指针)_算法_05

四、最接近的三数之和

两数之和、三数之和(排序+双指针)_while循环_06


​​最接近的三数之和​​

未排序,直接暴力回溯,超时

class Solution {
public:
vector<int> choice;
int gap = INT_MAX;
int target_;
int ans;

void func(int i, const vector<int>& nums){
if(choice.size() == 3){
int sum = accumulate(choice.begin(), choice.end(), 0);
if (abs(target_ - sum) < gap) {
ans = sum;
gap = abs(target_ - sum);
}
}else{
for(int j = i; j < nums.size(); j++){
choice.push_back(nums[j]);
func(j + 1, nums);
choice.pop_back();
}
}
}

int threeSumClosest(vector<int>& nums, int target) {
target_ = target;
func(0, nums);
return ans;
}
};

两数之和、三数之和(排序+双指针)_while循环_07


排序+双指针

class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end(), less<int>());
long ans = INT_MAX;

for(int l = 0; l < (int)nums.size() - 2; l++){
int mid = l + 1;
int r = nums.size() - 1;
while(mid < r){
int sum = nums[l] + nums[mid] + nums[r];
if(abs(sum - target) < abs(ans - target)){
// sum和target的距离减小,则更新ans
ans = sum;
}
if(sum == target){
// 和为target,则距离target最近,为0,返回当前sum
return sum;
}else if(sum > target){
r--;
}else{
mid++;
}
}
}
return ans;
}
};


举报

相关推荐

0 条评论