DAY6 哈希表part02
今日任務
● 454.四數相加II
● 383. 贖金信
● 15. 三數之和
● 18. 四數之和
● 總結
454.四數相加II
題目鏈接/文章講解/視頻講解:https://programmercarl.com/0454.%E5%9B%9B%E6%95%B0%E7%9B%B8%E5%8A%A0II.html
1 class Solution { 2 public: 3 int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) { 4 std:: unordered_map<int,int> map; 5 for(int a :nums1) 6 for(int b:nums2) 7 map[a+b]++; 8 9 int count=0; 10 for(int c:nums3) 11 for(int d:nums4) 12 { 13 if(map.find(-c-d)!=map.end()) 14 count+=map[-c-d]; 15 } 16 return count; 17 } 18 };
383. 贖金信
題目鏈接/文章講解:https://programmercarl.com/0383.%E8%B5%8E%E9%87%91%E4%BF%A1.html
1 class Solution { 2 public: 3 bool canConstruct(string ransomNote, string magazine) { 4 int len1=ransomNote.size(); 5 int len2=magazine.size(); 6 7 int record[26]={0}; 8 9 if(len1>len2) return false; 10 11 for(int i=0;i<len2;i++) 12 { 13 record[magazine[i]-'a']++; 14 } 15 for(int i=0;i<len1;i++) 16 { 17 record[ransomNote[i]-'a']--; 18 } 19 for(int i=0;i<26;i++) 20 if(record[i]<0) return false; 21 22 return true; 23 } 24 };
15. 三數之和
本題雖然和 兩數之和 很像,也能用哈希法,但用哈希法會很麻煩,雙指針法才是正解。
題目鏈接/文章講解/視頻講解:https://programmercarl.com/0015.%E4%B8%89%E6%95%B0%E4%B9%8B%E5%92%8C.html
1 class Solution { 2 public: 3 vector<vector<int>> threeSum(vector<int>& nums) { 4 vector<vector<int>> result; 5 sort(nums.begin(), nums.end()); 6 // 找出a + b + c = 0 7 // a = nums[i], b = nums[left], c = nums[right] 8 for (int i = 0; i < nums.size(); i++) { 9 // 排序之后如果第一個元素已經大于零,那么無論如何組合都不可能湊成三元組,直接返回結果就可以了 10 if (nums[i] > 0) { 11 return result; 12 } 13 // 錯誤去重a方法,將會漏掉-1,-1,2 這種情況 14 /* 15 if (nums[i] == nums[i + 1]) { 16 continue; 17 } 18 */ 19 // 正確去重a方法 20 if (i > 0 && nums[i] == nums[i - 1]) { 21 continue; 22 } 23 int left = i + 1; 24 int right = nums.size() - 1; 25 while (right > left) { 26 // 去重復邏輯如果放在這里,0,0,0 的情況,可能直接導致 right<=left 了,從而漏掉了 0,0,0 這種三元組 27 /* 28 while (right > left && nums[right] == nums[right - 1]) right--; 29 while (right > left && nums[left] == nums[left + 1]) left++; 30 */ 31 if (nums[i] + nums[left] + nums[right] > 0) right--; 32 else if (nums[i] + nums[left] + nums[right] < 0) left++; 33 else { 34 result.push_back(vector<int>{nums[i], nums[left], nums[right]}); 35 // 去重邏輯應該放在找到一個三元組之后,對b 和 c去重 36 while (right > left && nums[right] == nums[right - 1]) right--; 37 while (right > left && nums[left] == nums[left + 1]) left++; 38 39 // 找到答案時,雙指針同時收縮 40 right--; 41 left++; 42 } 43 } 44 45 } 46 return result; 47 } 48 };
18. 四數之和
建議: 要比較一下,本題和 454.四數相加II 的區別,為什么 454.四數相加II 會簡單很多,這個想明白了,對本題理解就深刻了。 本題 思路整體和 三數之和一樣的,都是雙指針,但寫的時候 有很多小細節,需要注意,建議先看視頻。
題目鏈接/文章講解/視頻講解:https://programmercarl.com/0018.%E5%9B%9B%E6%95%B0%E4%B9%8B%E5%92%8C.html

浙公網安備 33010602011771號