题1:
指路:LeetCode454 两数之和Ⅱ
思路及代码:
1.不瞒,看到这个题的第一反应还是暴力,不过很显然过不了全部。
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int n = nums1.size();
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n ; j++) {
for (int k = 0; k < n; k++) {
for (int l = 0; l < n; l++) {
if (nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0)
ans += 1;
}
}
}
}
return ans;
}
};
2.哈希
既然O(n^4)过不了,那就试试降低复杂度,我们用一个map哈希表盛放第一个数组和第二个数组的和及各个和出现的次数,再在另外两个数组中求和,找到与哈希表中满足条件对应的数出现的次数,相加即可。代码如下:
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]++; // 统计a+b及出现的次数
}
}
int cnt = 0; // 计数器
for (int c : nums3) {
for (int d : nums4) {
if (map1.find(0 - (c + d)) != map1.end()) // 第三和第四个数组中元素的和在map中出现过
cnt += map1[0 - (c + d)];
}
}
return cnt;
}
};
题2:
指路: LeetCode383 赎金信
思路与代码:
相似于LeetCode242 有效的字母异位词,关于这个题的讲解在有效的字母异位词第一题的位置。这里我们直接看代码:
1.暴力:
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
for (int i = 0; i < magazine.length(); i++) {
for (int j = 0; j < ransomNote.length(); j++) {
if (magazine[i] == ransomNote[j]) {
ransomNote.erase(ransomNote.begin() + j); //删除相同字符,如果最后没有东西则能组成,有东西则不能
break;
}
}
}
if (ransomNote.length() == 0) // 相同字符全被删除了
return true;
return false;
}
};
2.哈希:
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int h[26];
for (int i = 0; i < magazine.length(); i++) {
h[magazine[i] - 'a']++;
}
for (int i = 0; i < ransomNote.length(); i++) {
h[ransomNote[i] - 'a']--;
if (h[ransomNote[i] - 'a'] < 0) // 次数小于0则不能构成
return false;
}
return true;
}
};