代码随想录算法训练营第六天 - 哈希表2 || 454.四数相加II / 383.赎金信 / 15.三数之和 / 18.四数之和
454.四数相加II
文档讲解:代码随想录算法训练营
视频讲解:算法视频公开课
状态:思路自己想出来了,但代码没有实现出来
解题思路
首先如果使用暴力方法,也就是对数组nums1到nums2依次遍历,直到找到符合要求的组合,那么时间复杂度为O(n^4)。
如何能减少时间复杂度呢?
想到之间 242.有效字母异位词 的解法,我们可以遍历nums1和nums2,求出二者num1 + num2之和的组合,并记录出现的次数。
接着,我们再遍历nums3和nums4,现在我们的目标值是找到target = 0 - num3 - num4,因为题目要求num1 + num2 + num3 + num4 = 0,也就是要找num1 + num2 = - (num3 + num4)。然后在map里找target是否出现过,如果出现过,计数的变量count要加上target在map里的value值,即target在map里存储的次数。
代码实现:
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int> map;
// 遍历 nums1 和 nums2
for (int num1 : nums1) {
for (int num2 : nums2) {
map[num1 + num2] ++;
}
}
int count = 0;
// 遍历 nums3 和 nums4
for (int num3 : nums3) {
for (int num4 : nums4) {
int target = 0 - num3 - num4;
if (map.find(target) != map.end()) {
count += map[target];
}
}
}
return count;
}
};
383.赎金信
文档讲解:代码随想录算法训练营
状态:自己完全做出来了
自己解答:
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
unordered_map<int,int> map;
// 遍历 magazine 字符串
for (int i = 0; i < magazine.size(); i++) {
map[magazine[i] - 'a'] ++;
}
// 遍历 ransomNote 字符串
for (int i = 0; i < ransomNote.size(); i++) {
map[ransomNote[i] - 'a'] --;
}
// 是否有 value < 0,如果有就不能构成
for (int i = 0; i < 26; i++) {
if (map[i] < 0) return false;
}
return true;
}
};
代码随想录讲解
暴力做法
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
// 遍历 magazine 和 ransomNote
for (int i = 0; i < magazine.size(); i++) {
for (int j = 0; j < ransomNote.size(); j++) {
// 如果找到相同字符,就把这个字符从 ransomNote里删除
if (magazine[i] == ransomNote[j]) {
ransomNote.erase(ransomNote.begin() + j);
}
}
}
// 如果 ransomNote 里还有字符,那么就不构成
if (ransomNote.length() != 0) return false;
return true;
}
};
哈希表
题目说只有小写字母,采用空间换取时间的哈希策略,用一个长度为26的数组来记录magazine出现字母的次数。
为什么不采用map呢,因为map要维护红黑树或者哈希表,而且还要做哈希函数,是费时的!数据量大的话就能体现出来差别了。 所以数组更加简单直接有效!
class Solution {
public:

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



