总结
454.四数之和II
四重循环铁超时,故空间换时间,先两层循环存下来和,再两层循环查找即可;
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
map<int,int> M;
int n=nums1.size();
int ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
M[nums1[i]+nums2[j]]++;
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int x=0-nums3[i]-nums4[j];
if(M[x]) ans+=M[x];
}
}
return ans;
}
};
383.赎金信
只要字符M包括字符R的所有字符即可,简单来说,就是R有的M都得有,可以多不能少;
ps:随想录代码思路跟我这个一样hh
int cnt[26];
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
memset(cnt,0,sizeof cnt);
int lenr=ransomNote.size();
int lenm=magazine.size();
for(int i=0;i<lenr;i++) cnt[ransomNote[i]-'a']++;
for(int i=0;i<lenm;i++) cnt[magazine[i]-'a']--;
for(int i=0;i<26;i++){
if(cnt[i]>0) return false;
}
return true;
}
};
15.三数之和
这道题我是卡住了,想到了排序+双指针,没想到剩下的那个数直接暴力循环就行;
思路
1.先排序,左右指针可以确定两个数,第三个数循环确定;
2.大于0右指针–,小于0左指针++;
3.倘若第一个数就>0,可以直接返回了,这是剪枝操作;
4.去重操作有三部分,i的去重是跟前面比,防止漏过-1 -1 2类似的情况;l跟r的去重是在找到一个三元组之后;
5.找到三元组后,左右指针都移动,找下一个以i为开头的三元组;
注意
1.去重尤其注意,同一个三元组元素是可以重复的,所以去重i的时候是跟i-1比;左右指针是在找到一个三元组之后再移动;
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ans;
sort(nums.begin(),nums.end());
if(nums[0]>0) return ans;
int len=nums.size();
for(int i=0;i<len;i++){
if(i>0&&nums[i]==nums[i-1]) continue;
int l=i+1,r=len-1;
while(l<r){
if(nums[i]+nums[l]+nums[r]>0) r--;
else if(nums[i]+nums[l]+nums[r]<0) l++;
else{
ans.push_back(vector<int>{nums[i], nums[l], nums[r]});
while(l<r&&nums[l]==nums[l+1]) l++;
while(l<r&&nums[r]==nums[r-1]) r--;
r--;
l++;
}
}
}
return ans;
}
};
18.四数之和
思路基本跟三数之和一样,这里数据范围变小,故可以来两重循环确定两个数,再左右指针确定两个数;
加和可能爆int,注意开long long;
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> ans;
sort(nums.begin(),nums.end());
int len=nums.size();
for(int i=0;i<len;i++){
if(nums[i]>target&&nums[i]>=0) break;
if(i>0&&nums[i]==nums[i-1]) continue;
for(int j=i+1;j<len;j++){
if(nums[j]+nums[i]>target&&nums[j]+nums[i]>=0) break;
if(j>i+1&&nums[j]==nums[j-1]) continue;
int l=j+1;
int r=len-1;
while(l<r){
if((long long)nums[i]+nums[j]+nums[l]+nums[r]>target) r--;
else if((long long)nums[i]+nums[j]+nums[l]+nums[r]<target) l++;
else{
ans.push_back(vector<int>{nums[i],nums[j],nums[l],nums[r]});
while(l<r&&nums[r]==nums[r-1]) r--;
while(l<r&&nums[l]==nums[l+1]) l++;
r--;
l++;
}
}
}
}
return ans;
}
};