1. Two Sum
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
法一: 利用排序+对撞指针,时间复杂度O(nlogn),空间复杂度O(1)
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res;
int i = 0, j = nums.size() - 1;
while(left < right)
{
if(nums[i] + nums[j] == target)
{
res.push_back({i, j});
break;
}
else if(nums[i] + nums[j] < target)
i ++;
else
j --;
}
return res;
}
法二: 空间换时间,时间复杂度O(n),空间复杂度O(n)
vector<int> twoSum(vector<int>& nums, int target) {
map<int, int> mp;
vector<int> res;
for(int i = 0; i < nums.size(); i++)
{
if(mp.find(target - nums[i]) != mp.end())
{
res= {mp[target- nums[i]], i};
break;
}
else
mp[nums[i]] = i;
}
return res;
}
15. 3Sum
Given an array nums
of n integers, are there elements a, b, c in nums
such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
The solution set must not contain duplicate triplets.
法:外层循环+2sum,注意去重,时间复杂度O(n^2),空间复杂度O(1)
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
if(nums.size() < 3)
return res;
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size() - 2; i ++)
{
if(i > 0 && nums[i] == nums[i - 1])
continue;
int left = i + 1, right = nums.size() - 1;
while(left < right)
{
if(nums[left] + nums[right] == -nums[i])
{
vector<int> result = {nums[i], nums[left ++], nums[right --]};
res.push_back(result);
while(left < right && nums[left] == nums[left-1])
left++;
while(left < right && nums[right] == nums[right+1])
right--;
}
else if(nums[left] + nums[right] > -nums[i])
right --;
else
left ++;
}
}
return res;
}
16. 3Sum Closest
Given an array nums
of n integers and an integer target
, find three integers in nums
such that the sum is closest to target
. Return the sum of the three integers. You may assume that each input would have exactly one solution.
法:与3sum类似,可以不去重,时间复杂度O(n^2),空间复杂度O(1)
int threeSumClosest(vector<int>& nums, int target) {
int res = 0;
int mgap = INT_MAX;
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size() - 2; i ++)
{
int j = i + 1;
int k = nums.size() - 1;
while(j < k)
{
int gap = abs(nums[i] + nums[j] + nums[k] - target);
if(gap < mgap)
{
res = nums[i] + nums[j] + nums[k];
mgap = gap;
}
if(nums[i] + nums[j] + nums[k] < target)
j ++;
else
k --;
}
}
return res;
}
18. 4Sum
Given an array nums
of n integers and an integer target
, are there elements a, b, c, and d in nums
such that a+ b + c + d = target
? Find all unique quadruplets in the array which gives the sum of target
.
Note:
The solution set must not contain duplicate quadruplets.
法:双层层循环+2sum,注意去重,时间复杂度O(n^3),空间复杂度O(1)
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> res;
if(nums.size() < 3)
return res;
sort(nums.begin(), nums.end());
for(int j = 0; j <nums.size() - 3; j ++)
{
if(j > 0 && nums[j] == nums[j - 1])
continue;
for(int i = j + 1; i < nums.size() - 2; i ++)
{
if(i > j + 1 && nums[i] == nums[i - 1])
continue;
int left = i + 1, right = nums.size() - 1;
while(left < right)
{
if(nums[left] + nums[right] == target-nums[i]-nums[j])
{
vector<int> result = {nums[j], nums[i], nums[left ++], nums[right --]};
res.push_back(result);
while(left < right && nums[left] == nums[left-1])
left++;
while(left < right && nums[right] == nums[right+1])
right--;
}
else if(nums[left] + nums[right] > target-nums[i]-nums[j])
right --;
else
left ++;
}
}
}
return res;
}
454. 4Sum II
Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l)
there are such that A[i] + B[j] + C[k] + D[l]
is zero.
To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 2^31 - 1.
法:2sum+2sum,记录2sum的值,时间复杂度O(n^2),空间复杂度O(n^2)
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
if(A.size() == 0)
return 0;
int res = 0;
int N = A.size();
unordered_map<int, int> mp;
for(int i = 0; i < N; i ++)
for(int j = 0; j < N; j++)
mp[A[i] + B[j]] ++;
for(int i = 0; i < N; i ++)
for(int j = 0; j < N; j ++)
{
if(mp.find(-C[i]-D[j]) != mp.end())
res += mp[-C[i]-D[j]];
}
return res;
}
总结
1.排序后前后指针对撞。
2.空间换时间,用hashmap存储中间结果、