代码随想录算法训练营第七天| 454.四数相加II、383. 赎金信、15. 三数之和、18. 四数之和
454.四数相加II
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int, int> rec;
int i, j, size = nums1.size(), ans = 0;
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
rec[nums1[i]+nums2[j]]++;
}
}
for(i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
auto it = rec.find(-nums3[i]-nums4[j]);
if (it != rec.end()) ans += it->second;
}
}
return ans;
}
};
和 “1. 两数之和” 相似,将元素保存在key中,将次数或下标保存在value中
383. 赎金信
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int rec[26] = {0};
for (char c : magazine) rec[c - 'a']++;
for (char c : ransomNote)
if (--rec[c - 'a'] < 0) return false;
return true;
}
};
使用数组记录方便些
15. 三数之和
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ans;
sort(nums.begin(), nums.end());
int i, left, right, size = nums.size();
for (i = 0; i < size - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) continue;
left = i + 1, right = size - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum > 0) {
right--;
} else if (sum < 0) {
left++;
} else {
ans.push_back({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++;
}
}
}
return ans;
}
};
去重和去重时机是关键
18. 四数之和
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> ans;
sort(nums.begin(), nums.end());
int i, j, left, right, size = nums.size();
for (i = 0; i < size - 3; i++) {
if (i > 0 && nums[i] == nums[i - 1]) continue;
for (j = i + 1; j < size - 2; j++) {
if (j > i + 1 && nums[j] == nums[j - 1]) continue;
left = j + 1, right = size - 1;
while (left < right) {
long long sum = (long long) nums[i] + nums[j] + nums[left] + nums[right];
if (sum > target) {
right--;
} else if (sum < target) {
left++;
} else {
ans.push_back({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++;
left++, right--;
}
}
}
}
return ans;
}
};
思路和上一题一样,要明白双指针的作用