1.two sum
思路:一次遍历+hash
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int,int> a; vector<int> b; for(int i = 0; i < nums.size(); i++) { a[nums[i]] = i; } for(int i = 0; i < nums.size(); i++) { int x = target - nums[i]; if(a.count(x) && a[x] != i) { b.push_back(i); b.push_back(a[x]); break; } } return b; } };
167. Two Sum II - Input array is sorted
思路:双指针遍历
class Solution { public: vector<int> twoSum(vector<int>& numbers, int target) { vector<int> a; if(numbers.empty()) { return a; } int l = 0,r = numbers.size()-1; while(l < r) { if(numbers[l] + numbers[r] < target){ l++; } else if(numbers[l] + numbers[r] > target) { r--; } else { a.push_back(l+1); a.push_back(r+1); break; } } return a; } };
15.3sum
//问题:找数组中和为0的三元组
//方法:排序后,扫描数组,转化为2sum问题
//2sum对应一个循环,3sum对应两重循环,4sum对应三重循环
class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int> > a; if(nums.size() < 3) return a; sort(nums.begin(),nums.end()); for(int i = 0; i < (int)nums.size()-2; i++) { if(nums[i] > 0) break; if(i > 0 && nums[i-1] == nums[i]) //相同则继续找下一个数 continue; int l = i+1,r = (int)nums.size() - 1; int target = 0-nums[i]; while(l < r) { if(nums[l] + nums[r] == target) { a.push_back({nums[i],nums[l],nums[r]}); while(l < r&&nums[l] == nums[l+1]) //如果相同则继续找下个数 l++; while(l < r&&nums[r] == nums[r-1]) r--; l++,r--; } else if(nums[l] + nums[r] < target) l++; else r--; } } return a; } };
16.3sum closest
问题:离目标值最近的三数之和
方法:排序后,扫描a[i],后面在用left和right首尾两指针扫描
class Solution { public: int threeSumClosest(vector<int>& nums, int target) { if(nums.size() < 3) return 0; int closest = nums[0] + nums[1] + nums[2]; int diff = abs(closest - target); sort(nums.begin(),nums.end()); for(int i = 0; i < nums.size() - 2; i++) { int l = i+1, r = nums.size() - 1; while(l < r) { int sum = nums[i] + nums[l] + nums[r]; int x = abs(sum - target); if(x < diff) { diff = x; closest = sum; } if(sum < target) l++; else r--; } } return closest; } };
18.4sum
/*
问题:找与目标值相等的4个数
三重循环即可
用set可避免重复结果
*/
class Solution { public: vector<vector<int>> fourSum(vector<int>& nums, int target) { if(nums.size() < 4) return vector<vector<int>>(); set<vector<int>> res; sort(nums.begin(),nums.end()); for(int i = 0; i < nums.size()-3; i++) { for(int j = i+1; j < nums.size() - 2; j++) { int l = j + 1,r = nums.size() - 1; while(l < r) { int sum = nums[i] + nums[j] + nums[l] + nums[r]; if(sum == target) { vector<int> s{nums[i],nums[j],nums[l],nums[r]}; res.insert(s); //set有重复时插入不进去 l++,r--; } else if(sum > target) { r--; } else{ l++; } } } } return vector<vector<int>> (res.begin(),res.end()); //讲set转为vector输出 } };
217. Contains Duplicate
问题:判断一个数组是否含重复元素
方法:用map统计每个元素出现的次数
此题比较简单,方法很多
class Solution { public: bool containsDuplicate(vector<int>& nums) { unordered_map<int,int> dict; for(int i:nums) { dict[i]++; if(dict[i] > 1) { return true; } } return false; } };
26. Remove Duplicates from Sorted Array
问题:去除有序序列中的重复数字
方法一:双指针法(覆盖法)
当a[i] != a[index-1] 用a[i]覆盖a[index]
相等时不覆盖,不等时覆盖,index代表了新数组的索引,i代表了旧数组索引,将无重复数依次移动到前面
class Solution { public: int removeDuplicates(vector<int>& nums) { if(nums.empty()) { return 0; } int index = 1; for(int i = 0; i < nums.size(); i++) { if(nums[i] != nums[index-1]){ nums[index] = nums[i]; index++; } } return index; } };