1. two sum
下面有c++ 和Python代码
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.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
由于一样的元素只能用一次,涉及查找,map肯定是最快的。map<int,int>存下标
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target)
{
map<int,int> index;
index[nums[0]] = 1;
for(int i = 1; i < nums.size() ;i++)
{
int key = target - nums[i];
if (index.find(key) != index.end())
{
vector<int> ret(1, index[key]);
ret.push_back(i + 1);
return ret;
}
else
index[nums[i]] = i + 1;
}
}
};
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
d = {}
d[nums[0]] = 0
size = 1
while size < len(nums):
if target - nums[size] in d:
ret = [d[target - nums[size]], size]
return ret
if not nums[size] in d:
d[nums[size]] = size
size += 1
167. Two Sum II - Input array is sorted
Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution and you may not use the same element twice.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
两个指针往中间移动,这种找出两个数的这种题应该想到两个指针!!
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target)
{
vector<int> ret;
int left = 0;
int right = nums.size() - 1;
while (left < right)
{
if (nums[left] + nums[right] == target)
{
ret.push_back(left+1);
ret.push_back(right+1);
return ret;
}
else if (nums[left] + nums[right] < target)
left++;
else
right--;
}
}
};
3. three SUM
Given an array S of n integers, are there elements a, b, c in S 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.
For example, given array S = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
解题思路:先排序,大的在后面,固定首个数字,然后 两个指针往中间移动 ,确定剩下两个数字。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums)
{
sort(nums.begin(), nums.end());
int target, left, right;
vector<vector<int>> result;
if (nums.size() == 0)
return result;
vector<int> m1;
for (int i = 0; i < nums.size() - 2; i ++)
{
target = -nums[i];
if (nums[i] > 0) //因为后面的都是更大的数,直接不用再找了
break;
if (i > 0 && nums[i] == nums[i-1]) //减少重复查找
continue;
left = i + 1;
right = nums.size() - 1;
while (left < right)
{
if (nums[left] + nums[right] == target)
{
m1.push_back(nums[i]);
m1.push_back(nums[left]);
m1.push_back(nums[right]);
result.push_back(m1);
if (result[result.size()-1] == result[result.size()-2]) //去除重复
result.erase(result.end());
m1.clear();
right --;
left ++;
}
else if (nums[left] + nums[right] > target)
right --;
else
left ++;
}
}
return result;
}
};
16. 3Sum Closest
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
For example, given array S = {-1 2 1 -4}, and target = 1.
The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
题目:3sum最接近target
思路:和3sum一样,先排序,固定第一个数,两个指针移动后两个数,往中间移动。
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target)
{
if (nums.size() == 0)
return 0;
int targ;
int result = 0;
int small = INT_MAX;
sort(nums.begin(), nums.end());
int left, right;
for (int i = 0;i < nums.size() - 2; i++)
{
targ = target - nums[i];
left = i + 1;
right = nums.size() - 1;
while (left < right)
{
if (abs(nums[left] + nums[right] - targ) < small)
{
small = abs(nums[left] + nums[right] - targ);
result = nums[left] + nums[right] + nums[i];
}
if (nums[left] + nums[right] > targ)
right --;
else if (nums[left] + nums[right] < targ)
left ++;
else
return target;
}
}
return result;
}
};
18. 4Sum
Given an array S of n integers, are there elements a, b, c, and d in S 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.
For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0.
A solution set is:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
way-1:两重for固定两个数,两个指针移动确定后两个数
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target)
{
//way-1
vector<vector<int>> result;
if (nums.size() < 4)
return result;
vector<int> m1;
sort(nums.begin(), nums.end());
int left, right;
for (int i = 0; i < nums.size() - 3; i++)
{
if (i > 0 && nums[i] == nums[i-1])
continue;
for (int j = i + 1; j < nums.size() - 2; j++)
{
if (j > i + 1 && nums[j] == nums[j-1])
continue;
left = j + 1;
right = nums.size() - 1;
while (left < right)
{
if (nums[i]+nums[j]+nums[left]+nums[right] > target)
right --;
else if (nums[i]+nums[j]+nums[left]+nums[right] < target)
left ++;
else
{
m1.push_back(nums[i]);
m1.push_back(nums[j]);
m1.push_back(nums[left]);
m1.push_back(nums[right]);
if(result.empty() || (result.size() > 0 && m1 != result[result.size()-1]))
result.push_back(m1);
m1.clear();
right --;
left ++;
}
}
}
}
return result;
}
};
way-2:先对给定数组做初始化,把所有两两值的和求出来,我们就把求4Sum变为求2Sum了,注意初始化的时候求两两和值也要保存两个数字的下标,题中我用的是multimap <int, pair < int, int > >,因为可能会有重复的所以要用multimap, multimap第一个int是表示和值,第二个pair是两个数的下标,而且用multimap我们默认是排序的,刚好初始化完直接用首和尾指针查找满足2Sum为0的数可以了。下标我们都记录着,所以很容易得到原先的4个值。找到4个值后我们把它保存在set中,这样也满足题意的要求返回值是有序的。
vector<vector<int>> ret;
if (nums.size() < 4)
return ret;
else if (nums.size() == 4)
{
if (accumulate(nums.begin(), nums.end(), 0) == target)
{
ret.push_back(nums);
return ret;
}
}
multimap<int,pair<int,int>> mm;
for (int i = 0; i < nums.size(); i++)
for (int j = i + 1;j < nums.size(); j++)
mm.insert({nums[i] + nums[j], {i,j}}); //注意map中有pair的插入方式!
for (auto i = mm.begin(); i != mm.end(); i++)
{
int x = target - i->first;
auto range = mm.equal_range(x); // multimap.equal_range(key)使用一定要会!
for(auto j = range.first; j != range.second; j++) //range.second指向最后一个查询结果的下一位置,有点像迭代器的end()
{
int a = i->second.first;
int b = i->second.second;
int c = j->second.first;
int d = j->second.second;
if(a!=b && a!=c && a!=d && b!=c && b!=d && c!=d)
{
vector<int> m1 = {nums[a], nums[b], nums[c], nums[d]};
sort(m1.begin(), m1.end());
ret.push_back(m1);
}
}
}
sort(ret.begin(), ret.end());
ret.erase(unique(ret.begin(), ret.end()), ret.end());
return ret;