最近有事迟了几天,马上补上,加油❤️。
454.四数相加II
第一想法是俩俩组队,nums1和nums2先搭配,nums3和nums4搭配;
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int n = nums1.size();
int ans = 0;
unordered_map<int, int> mp1;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
mp1[nums1[i] + nums2[j]]++;
}
}
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(mp1.count(0 - nums3[i] - nums4[j])){
ans += mp1[0 - nums3[i] - nums4[j]];
}
}
}
return ans;
}
};
383. 赎金信
很显然要快速在集合magazine中找到ransomNote,哈希表很明确
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
unordered_map<char, int> mp;
for(char ca : magazine){
mp[ca]++;
}
for(char ca : ransomNote){
if(!mp.count(ca)){
return false;
}else{
mp[ca]--;
if(mp[ca] == 0){
mp.erase(ca);
}
}
}
return true;
}
};
15. 三数之和
这题的第一感觉还是哈希表,但是去重的逻辑确实很难,看了答案,发现双指针确实巧妙,但是驱去重逻辑也一样的难
class Solution {
public:
// 双指针,关键在于去重时机和方法。
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
int n = nums.size();
vector<vector<int>> ans;
for(int i = 0; i < n; i++){ // 第一个数,也是最小的数
if(nums[i] > 0){ // 不能取=,会漏掉0,0,0这些
return ans;
}
if(i >= 1 && nums[i] == nums[i - 1]){ // 要向前去重,向后去重会减少后j, k的取值范围
continue;
}
int j = i + 1;
int k = n - 1;
while(j < k){
if(nums[i] + nums[k] + nums[j] > 0){
k--;
}else if(nums[i] + nums[k] + nums[j] < 0){
j++;
}else{ // 找到了满足条件的数,要注意去重方向
ans.push_back({nums[i], nums[j], nums[k]});
while(j < n -1 && nums[j] == nums[j + 1]){
j++;
}
while(k > 0 && nums[k] == nums[k - 1]){
k--;
}
j++;
k--;
}
}
}
return ans;
}
};
18. 四数之和
和三数之和类似
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
int n = nums.size();
vector<vector<int>> res;
sort(nums.begin(), nums.end());
for(int i = 0; i < n - 3; i++){
if((long)nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) return res;
if(i > 0 && nums[i] == nums[i - 1]) continue;
for(int j = i + 1; j < n - 2; j++){
if((long) nums[j] + nums[i] + nums[j + 1] + nums[j + 2]> target) break;
if(j > i + 1 && nums[j] == nums[j - 1]) continue;
int left = j + 1, right = n - 1;
while(left < right){
if((long)nums[i] + nums[j] + nums[left] + nums[right] > target) right--;
else if((long)nums[i] + nums[j] + nums[left] + nums[right] < target) left++;
else{
res.push_back({nums[i], nums[j], nums[left], nums[right]});
while(right > left && nums[right] == nums[right - 1]) right--;
while(right > left && nums[left] == nums[left + 1]) left++;
right--;
left++;
}
}
}
}
return res;
}
};

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



