1. 两数之和
问题描述
给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
解题思路
使用map来存储容器中的元素和数组下标,判断target - nums[i]
是否在map中,如果不在,返回{}
,如果在判断元素nums[i]
数组下标的和nums[target - nums[i]]
的数组下标是否一致,只有在不一致时才符合题意。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
代码实现
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
//数组元素个数多于3个,数组中没有重复的数字
// 数组只有两个数,数组中可能有重复的数字
map<int, int> iimap;
int j = 0;
for(auto& i : nums)
iimap[i] = j++;
for(int i = 0; i < nums.size(); i++){
if(iimap.find(target - nums[i]) != iimap.end() and iimap[target - nums[i]] != i){
return {i, iimap[target - nums[i]]};
}
}
return {};
}
};
2. 三数之和
问题描述
给你一个包含 n
个整数的数组 nums
,判断nums
中是否存在三个元素 a,b,c
,使得 a + b + c = 0
?请你找出所有满足条件且不重复的三元组。
注意: 答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
解题思路
- 为避免出现重复读取,可将数组排序后再找符合题意的三元组。出现连续相等的元素,直接跳过。
- 使用双指针的方法,从左只有每次固定一个元素,再在其元素后用两个指针寻找两个元素和为其固定元素负值即可满足题意。
- 双指针的开始位置是:左边指针指向固定元素的后一个位置;右指针指向元素最右边。如果两个指针指向的元素和大于固定值的负值,右指针减一;小于固定值的负值,左指针加一;直到相等,压入二维数组中。
代码实现
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n = nums.size();
sort(nums.begin(), nums.end());
vector<vector<int>> ans;
for(int first = 0; first < n; first++){
if(first > 0 and nums[first] == nums[first - 1])
continue;
int third = n - 1; //将此行代码放到下面的for循环里面 就会超时
int target = -nums[first];
for(int second = first + 1; second < n; second++){
if(second > first + 1 and nums[second] == nums[second - 1])
continue;
while(second < third and nums[second] + nums[third] > target){
third--;
}
if(second == third)
break;
if(nums[second] + nums[third] == target){
ans.push_back({nums[first], nums[second], nums[third]});
}
}
}
return ans;
}
};
运行截图
3、最接近的三数之和
问题描述
给定一个包括n
个整数的数组 nums
和 一个目标值target
。找出 nums
中的三个整数,使得它们的和与 target
最接近。返回这三个数的和。假定每组输入只存在唯一答案。
示例:
输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
提示:
3 <= nums.length <= 10^3
-10^3 <= nums[i] <= 10^3
-10^4 <= target <= 10^4
解题思路
使用上一题“三个数之和为零”的双指针法。将数组中元素排序,从左到右每次固定一个元素,再计算包括其元素与其后面的3个元素和。三元素和与target值相比较,最后返回其绝对值最小的三元组的和。
代码实现
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
if(nums.size() == 3)
return accumulate(nums.begin(), nums.end(), 0);
int ans = 0;
int n = nums.size();
sort(nums.begin(), nums.end());
int minnum = INT_MAX, tmp = 0;
for(int first = 0; first < n; first++){
int second = first + 1, third = n - 1;
while(second < third){
tmp = nums[first] + nums[second] + nums[third];
if(tmp == target)
return target;
if(abs(tmp - target) < minnum){
minnum = abs(tmp - target);
ans = tmp;
}
if(tmp > target)
third--;
else
second++;
}
}
return ans;
}
};
运行截图
4、四数之和
问题描述
给定一个包含n
个整数的数组nums
和一个目标值 target
,判断nums
中是否存在四个元素a,b,c
和d
,使得a + b + c + d
的值与target
相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。
示例:
给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。
满足要求的四元组集合为:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
解题思路
首先将序列从小到大排序,依次从左只有固定每一个元素,其余的元素按照求三数之和的方法即可。
代码实现
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
int n = nums.size();
vector<vector<int> > ans;
sort(nums.begin(), nums.end());
for(int first = 0; first < n; first++){
if(first > 0 and nums[first] == nums[first - 1])
continue;
for(int second = first + 1; second < n; second++){
int tar = target - (nums[first] + nums[second]);
if(second > first + 1 and nums[second] == nums[second - 1])
continue;
int fourth = n - 1;
for(int third = second + 1; third < fourth; third++){
if(third > second + 1 and nums[third] == nums[third - 1])
continue;
while(third < fourth and nums[third] + nums[fourth] > tar)
fourth--;
if(third == fourth)
break;
if(nums[third] + nums[fourth] == tar)
ans.push_back({nums[first], nums[second], nums[third], nums[fourth]});
}
}
}
return ans;
}
};
运行截图