两数之和
https://leetcode-cn.com/problems/two-sum/
思路:找一个数,再找一个满足和是target的数(第二次查找的范围和操作决定时间)
注意点
1:找的是数下标而不是本身,排序会加大难度(如使用二分查找,或双指针)
2:存在相同的数,使用hashmap才能存放key相同的元素
3:可利用只有唯一一个正确答案的条件,实现插入时查找
//map法 时间复杂度 nlogn
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ans;
map<int,int> m;
for( int i=0; i<nums.size(); i++ ){
if( m.find( target - nums[i] )!=m.end() ){
ans.push_back(i);
ans.push_back( m.find( target-nums[i])->second );
return ans;
}
m[nums[i]] = i;
}
return ans;
}
};
三数之和
https://leetcode-cn.com/problems/3sum/
思路:先找一个数,再在使用"两数之和"的方法把所有符合的数找到,循环
注意点
1:答案有多个,但每个答案唯一(
{1,0,-1},{-1,0,1}是一个答案 ,这意味着需要避免重复答案
第一个数会对应的多个满足的第二第三个数如{0,5,-5}{0,6,-6})
2:输出答案为数字本身,可对原数据集合进行排序
3:存在相同数据,并不是三个数各不相同如{0,0,0}
//双指针法(双指针法用于两数之和,当要求数据集合可排序)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort( nums.begin(), nums.end() ); //排序使数组左小右大
vector<vector<int>> ans;
int l , r ;
for( int i=0; i<nums.size(); i++ ){
//依次寻找第一个数nums[i]
if( i!=0 && nums[i]==nums[i-1] ){ //这步使得每次找的第一个数都不同
continue;
}
l = i+1 ;
r = nums.size()-1;
//遍历余下数组,找到所有满足能与第一个和为0的数
while( l<r ){
if( nums[l] + nums[r] + nums[i] > 0 ){ //大了
r--;
}else if( nums[l] + nums[r] + nums[i] < 0){ //小了
l++;
}else{
//满足
ans.push_back({ nums[i],nums[l],nums[r] });
l++;r--;
}
//这里用来跳过相同的数据
while( l<r && l!=i+1 && nums[l]==nums[l-1] ) l++;
while( l<r && r!=nums.size()-1 && nums[r]==nums[r+1] ) r--;
}
}
return ans;
}
};