454. 四数相加 II
添加链接描述
思路:这道题要求返回有几组,还好点,暴力的话就是四个for循环,优化一下的话,可以先将两个num1,nums2数组的和放在set中,然后将再set中寻找nums3与num4的和的相反数
代码:
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int> num;
for(int A:nums1)
{
for(int B:nums2)
{
num[A+B]++;
}
}
int count=0;
for(int C:nums3)
{
for(int D:nums4)
{
if(num.find(0-C-D)!=num.end())
{
count+=num[0-C-D];
}
}
}
return count;
}
};
383. 赎金信
思路:这道题简单一些,将一个字符串出现的字符计数,减去另一个出现的字符个数,出现-1则false反之true
代码:
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int record[26]={0};
for(int i=0;i<magazine.size();i++)
{
record[magazine[i]-'a']++;
}
for(int i=0;i<ransomNote.size();i++)
{
record[ransomNote[i]-'a']--;
if( record[ransomNote[i]-'a']<0)
return false;
}
return true;
}
};
15. 三数之和
添加链接描述
看到这题之后完全没有思路,直接头铁暴力做,结果去重又把我搞头晕了,看卡哥的题解,第一个是个哈希法,花了30分钟,去重部分没理解,又去看视频,感觉双指针的思路更好理解,这道题需要多写几遍
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();i++)
{
if(nums[i]>0)return result;
if(i>0&&nums[i]==nums[i-1])continue;
int right=nums.size()-1,left=i+1;
while(left<right)
{
if(nums[i]+nums[left]+nums[right]>0)right--;
else if(nums[i]+nums[left]+nums[right]<0)left++;
else
{
result.push_back(vector<int>{nums[i],nums[left],nums[right]});
while(right>left&&nums[left]==nums[left+1])left++;
while(right>left&&nums[right]==nums[right-1])right--;
right--;
left++;
}
}
}
return result;
}
};
18. 四数之和
这道题与上面的思路一样,双指针,只是这里的剪枝要注意:
if(nums[i]>target&&nums[i]>=0)break;//这里要注意为什么会有nums[i]>=0这是因为target可以是负数,负数与负数相加会更小,那么这里想要剪枝的话如果只是nums[i]>target,这里需要target>=0,即target>=0&&nums[i]>target&&nums[i]>=0,即nums[i]>target&&nums[i]>=0
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size();i++)
{
if(nums[i]>target&&nums[i]>=0)break;
if(i>0&&nums[i]==nums[i-1])continue;
for(int j=i+1;j<nums.size();j++)
{
if(nums[j]+nums[i]>target&&nums[j]+nums[i]>=0)break;
if(j>i+1&&nums[j]==nums[j-1])continue;
int left=j+1,right=nums.size()-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
{
result.push_back(vector<int>{nums[i],nums[j],nums[left],nums[right]});
while(left<right&&nums[left]==nums[left+1])left++;
while(left<right&&nums[right]==nums[right-1])right--;
left++;
right--;
}
}
}
}
return result;
}
};