454.四数相加II
总体思路为把头两个数组for嵌套起来,然后把头两个数组的和放到一个map里面。然后再做另一个for嵌套循环剩下的两个数组,判断剩下两个数组元素之和有没有和之前的map里面匹配的数据
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
std::unordered_map <int,int> map;
int sum =0;
int count =0;
for(int i =0;i<nums1.size();i++){
for(int j=0;j<nums2.size();j++){
sum = nums1[i] + nums2[j];
map[sum]++; //这句话的意思是如果sum没有出现则insert到map中,如果出现了,对他的value 做++;
}
}
int sum1 =0;
for(int i =0;i<nums3.size();i++){
for(int j=0;j<nums4.size();j++){
sum1 = nums3[i] + nums4[j];
auto iter = map.find(0 - sum1);
if(iter != map.end()) {
count = count +iter->second; //要注意这里不是count++; 因为要把a+b 的和符合的情况都加进去
}
}
}
return count;
}
};
383. 赎金信
这道题跟242题差不多,写法也差不多;
给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。
(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int storage[26] ={0};
for(int i=0;i<magazine.size();i++){
storage[magazine[i]-'a']++;
}
/*for(int i=0;i<26;i++){
if(storage[i]>1)
{storage[i] = 1;}
}*/
for(int i=0;i<ransomNote.size();i++){
storage [ransomNote[i] -'a']--;
}
for(int i=0;i<26;i++){
if(storage[i]<0)
return false;
}
return true;
}
};
15. 三数之和
这个题如果用哈希法很麻烦,会把所有符合条件的都存下来然后去重;所以采用的先排序,然后是双指针加一个for循环;
要注意去重的方式 nums[i] == nums[i - 1],而且所有选的元素都是在同一个数组中选的;continue会跳出当前循环并直接进入下一个循环
18. 四数之和
这个题和三数之和差不多,需要注意的是这个题要判断的是等于target的情况,target可能是负数,负数加负数会变小,所以不能和15题写当第一个元素大于target就返回;另一个区别就是加了一层循环
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 (k > 0 && nums[k] == nums[k - 1]) {
continue;}
for (int i = k+1; i < nums.size(); i++) {
if (i > k+1 && nums[i] == nums[i - 1]) {
continue;
}
int left = i + 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[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;
}