问题1:454. 四数相加 II - 力扣(LeetCode)
思路:该题用暴力法显然复杂度太高,因此需要采用map,先记录两个数的和出现的次数,键为两个数的和,然后再用map去寻找,若发现了则加上该位置的值。代码如下:
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int> countab;
for(int a:nums1){
for(int b:nums2) ++countab[a+b];
}
int result=0;
for(int a:nums3){
for(int b:nums4) {
if(countab.find(-a-b)!=countab.end()){
result+=countab[-(a+b)];
}
}
}
return result;
}
};
思路:先定义一个数组,长度为26,用来记录字符出现的次数,先遍历长度大的字符串,并在数组中相应的位置做自加,接着再遍历长度小的字符串,在相应位置做自减,若有发现数组中有小于0的存在,则返回false,代码如下:
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int dp[26]={0};
for(int j=0;j<magazine.size();j++){
dp[magazine[j]-'a']++;
}
for(int i=0;i<ransomNote.size();i++){
dp[ransomNote[i]-'a']--;
if(dp[ransomNote[i]-'a']<0) return false;
}
return true;
}
};
思路:双指针法。首先对数组进行排序,在对数组进行遍历时,定义一个right和left进行求和并与目标值比较,若大于则自减,小于则左自加;同时在各个部分做好去重语句,代码如下:
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 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]});
while(right>left && nums[right]==nums[right-1]) right--;
while(right>left && nums[left]==nums[left+1]) left++;
left++;
right--;
}
}
}
return result;
}
};
思路:在三数之和中多了一个循环和一些去重语句,代码如下:
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 k=i+1;k<nums.size();k++){
if(nums[i]+nums[k]>target && nums[i]+nums[k]>=0) break;
if(k>i+1 && nums[k]==nums[k-1]) continue;
int left=k+1;
int right=nums.size()-1;
while(right>left){
if((long) nums[k]+nums[i]+nums[left]+nums[right] > target) right--;
else if((long) nums[k]+nums[i]+nums[left]+nums[right] < target) {
left++;}
else {
result.push_back(vector<int>{nums[i],nums[k],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;
}
};