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

 

posted @ 2024-07-23 16:53  xzdmzrc  阅读(4)  评论(0编辑  收藏  举报