一、和为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 {};
}
};
二、两数之和
用和哈希表存储已经遍历过且没找到和为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 {};
}
};
三、三数之和
用排序+双指针的方法,时间复杂度为
O
(
N
2
)
O(N^2)
O(N2)
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());
}
};
四、最接近的三数之和
未排序,直接暴力回溯,超时
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;
}
};
排序+双指针
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;
}
};