454.四数相加II
文章链接:代码随想录 (programmercarl.com)
思路:该题不用考虑结果去重的操作。遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中,再遍历大C和大D数组,将0-(c+d)在map中寻找,如果存在,将value值统计出来。
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int>map;
for(int a:nums1)
{
for(int b:nums2)
{
map[a+b]++;
}
}
int count=0;
for(int c:nums3)
{
for(int d:nums4)
{
int target=0-(c+d);
if(map.find(target)!=map.end())
{
count+=map[target];
}
}
}
return count;
}
};
383.赎金信
文章链接:代码随想录 (programmercarl.com)
该题和有效字母的异位词一样的思路
思路:用一个长度为26的数组记录magazine里字母出现的次数:将这26个元素赋值为0,将magazine中拥有的字符,在数组中用record做记录,magazine里各个字符出现的次数,遍历ransom,在record里对应的字符个数做--操作,如果小于0,说明ransom中有的字符,magazine中没有。
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int record[26]={0};
if(ransomNote.size()>magazine.size())
{
return false;
}
for(int i=0;i<magazine.length();i++)
{
record[magazine[i]-'a']++;
}
for(int j=0;j<ransomNote.length();j++)
{
record[ransomNote[j]-'a']--;
if(record[ransomNote[j]-'a'] < 0)
{
return false;
}
}
return true;
}
};
15.三数之和
文章链接:代码随想录 (programmercarl.com)
思路:先对数组排序,对数组做遍历操作,然后对a做去重操作,去重操作是指不允许出现一样的三元组,但是三元组里面的元素是可重复的。三数之和与0比较,大于0,right做减减操作,小于0,left做加加操作,等于0,将结果存放于result,找到三元组之后,再对b c做去重操作。
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) //如果遍历到的第一个元素就大于0 那直接返回 就不存在三元组相加等于0的情况
{
return result;
}
//先对a做去重操作
if(i>0&&nums[i]==nums[i-1])
{
continue;
}//跳过该结果
int left=i+1;
int right=nums.size()-1;
while(right>left)
{
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]});
//找到一个三元组之后 对b c做去重操作
while(right>left&&nums[right]==nums[right-1])
{
right--;
}
while(right>left&&nums[left]==nums[left+1])
{
left++;
}
right--;
left++;
}
}
}
return result;
}
};
18.四数之和
文章链接:
思路:两层for循环,k与i是确定的,靠left和right不断向中间移动使四数相加等于target
首先对数组做排序,对k和i分别做剪枝和去重操作,之后将left和right移动,找到四数之和等于target之后,收集结果,再对nums[right]和nums[left]做一个去重操作
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;
sort(nums.begin(),nums.end());//对数组做排序
for(int k=0;k<nums.size();k++)
{
if(nums[k]>target&&nums[k]>=0)//对k剪枝
{
break;
}
if(k>0&&nums[k]==nums[k-1])//对k去重
{
continue;
}
for(int i=k+1;i<nums.size();i++)
{
if(nums[k]+nums[i]>target&&nums[k]+nums[i]>=0)//对i做剪枝
{
break;
}
if( i>k+1&&nums[i]==nums[i-1])//对i做去重
{
continue;
}
//加下来对left和right做移动操作,寻找四数之和相加等于target的情况,收集结果,再对nums[right]和nums[left]做一个去重操作
int left=i+1;
int right=nums.size()-1;
while(right>left)
{
if(nums[k]+nums[i]+nums[left]+nums[right]>target)
{
right--;
}
else if(nums[k]+nums[i]+nums[left]+nums[right]<target)
{
left++;
}
else
{
result.push_back(vector<int>{nums[k],nums[i],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 result;
}
};
以上代码参考代码随想录代码随想录 (programmercarl.com)