454.四数相加II
思路:
- 首先定义 一个unordered_map,key放a和b两数之和,value 放a和b两数之和出现的次数。
- 遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中。
- 定义int变量count,用来统计 a+b+c+d = 0 出现的次数。
- 在遍历大C和大D数组,找到如果 0-(c+d) 在map中出现过的话,就用count把map中key对应的value也就是出现次数统计出来。
- 最后返回统计值 count 就可以了
class Solution { public: int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) { unordered_map<int,int>map1; for(int a : nums1){ for(int b : nums2){ map1[a + b]++; } } int count = 0; for(int c : nums3){ for(int d : nums4){ if(map1.find(0-c-d)!=map1.end()){ count+=map1[0-c-d]; } } } return count; } };
383. 赎金信
思路:固定大小的26个字母可以用数组做。
class Solution { public: bool canConstruct(string ransomNote, string magazine) { int record[26] = {0}; for(int i = 0;i < ransomNote.length(); i++){ record[ransomNote[i] - 'a']++; } for(int i = 0; i < magazine.length(); i++){ record[magazine[i]-'a']--; } for(int i =0; i<26;i++){ if(record[i]>0){ return false; } } return true; } };
15. 三数之和
哈希表去重太麻烦考虑使用双指针。确定一边,然后令left再边的左边,right为nums.size()-1.遍历寻找重点是去重
class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> result; sort(nums.begin(),nums.end()); for(int i = 0; i< nums.size();i++){ int left = i + 1; int right = nums.size() - 1; if(i > 0 && nums[i] == nums[i-1]){ continue; } if(nums[i] > 0){ break; } while(left < right){ if((nums[i] + nums[left] + nums[right])==0){ result.push_back(vector<int>{nums[i],nums[left],nums[right]}); while(left < right && nums[right] == nums[right-1]){ right--; } while(left < right && nums[left] == nums[left+1]){ left++; } right--; left++; } else if((nums[i] + nums[left] + nums[right]) > 0 ){ right--; }else{ left++; } } } return result; } };
18. 四数之和
比三数之和多一个for循环。
我的代码没有减枝。可以更加完善。
class Solution { public: vector<vector<int>> fourSum(vector<int>& nums, int target) { vector<vector<int>> result; sort(nums.begin(),nums.end()); for(int i = 0 ; i < nums.size();i++){ if(i > 0 && nums[i] == nums[i-1]){ continue; } for(int j = i+1; j <nums.size();j++){ if(j>(i+1) && nums[j]==nums[j-1]){ continue; } int left = j + 1; int right = nums.size() - 1; while(left < right){ if(((long)nums[i] + nums[j] + nums[left] + nums[right]) == target){ result.push_back(vector<int>{nums[i],nums[j],nums[left],nums[right]}); while(left < right && nums[right] ==nums[right-1]){ right--; } while(left < right && nums[left] ==nums[left+1]){ left++; } right--; left++; }else if (((long)nums[i] + nums[j] + nums[left] + nums[right]) > target){ right--; }else{ left++; } } } } return result; } };