注意点:
1.首先先让num1和nums2相加,将值存在key中,value用来存储num1和nums中和出现的次数,所以采用unordered_map<int, int> map
2.在map中查找和0-num1-num2的值相等的key,通过两种方式,一种是如下图所示解答1. 两数之和https://leetcode.cn/problems/two-sum/
采用的方式,截图所示,本题代码利用count += map.find(0-(i+j))->second获得map的value,还有一种是直接map[0-(i+j)],获得map的value的值,最终返回count值。
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int, int> map;
for(auto i: nums1) {
for(auto j: nums2){
map[i+j]++;
}
}
int count = 0;
for(auto i: nums3) {
for(auto j: nums4){
if(map.find(0 - ( i + j)) != map.end())
// count += map[0-(i+j)];
count += map.find(0-(i+j))->second;
}
}
return count;
}
};
注意点:
1.选用数组速度比较快,首先建立一个26位的数组,遍历字符串中的每个字符,将获得的字符与“a”相减,转换为数组中的序数,a为0,b为1,c为3.....,遇到相同的字符直接++,第二个数组进行遍历,遇到和数组中一致的直接--,最后遍历看看每个字符是不是都<0,然后进行返回即可。
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']--;
for(int i = 0; i< 26; i++)
{
if(record[i] < 0)
return false;
}
return true;
}
};
// 时间复杂度: O(n)
// 空间复杂度:O(1)
注意点:
1.采用双指针的方式进行,首先得对头节点进行判断,如果头节点大于0,直接continue即可
2.然后i进行去重,当i=1时候,与前一个节点进行比较,如果相同直接跳过【0 0 0 0 0 0】
3.然后指针进行移动,这时候采用while和if都可以,如果结果大于0,right--,相反left++。
4.之后对left和right进行去重【-3 -1 -1 0 4 4 4 4 】
5.最后将所得的数据添加到数组中注意添加格式为result.push_back(vector<int>{nums[i], nums[left], nums[right]}); 数组中的数据是{}
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) break;
// 首先对i进行去重
if(i>0 && nums[i] == nums[i-1])
continue;
int left = i+1;
int right = nums.size()-1;
while(left < right) {
while(left < right && nums[i] + nums[left] +nums[right] >0) right--;
while(left < right && nums[i] + nums[left] +nums[right] <0) left++;
if(left < right && nums[i] + nums[left] +nums[right] ==0) {
result.push_back(vector<int>{nums[i], nums[left], nums[right]});
// 对left和right进行去重
while(left < right && nums[right] == nums[right-1]) right--;
while(left > right && nums[left] == nums[left+1]) left++;
left++;
right--;
/*
if(left < right && nums[i] + nums[left] +nums[right] >0) right--;
else if(left < right && nums[i] + nums[left] +nums[right] <0) left++;
else {
result.push_back(vector<int>{nums[i], nums[left], nums[right]});
while(left < right && nums[right] == nums[right-1]) right--;
while(left > right && nums[left] == nums[left+1]) left++;
left++;
right--;
*/
}
}
}
return result;
}
};
注意点:
1.参考上一个三个数之和,只不过在原来基础上新加了一层循环。主要注意的就是新加一层循环的剪枝操作,是b>a+1开始的
2.注意本次题目中数字可能会溢出,但是溢出的时候得在条件语句之前添加long,如代码中(long)nums[a] + nums[b] + nums[left] +nums[right] < target所示
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;
sort(nums.begin(), nums.end());
for(int a = 0;a <nums.size(); a++) {
if( target >0 && nums[a] > target) break;
if(a >0 && nums[a] == nums[a-1]) continue;
for(int b = a+1; b<nums.size(); b++) {
if(target >0 && nums[a] + nums[b] > target) break;
if(b >a+1 && nums[b] == nums[b-1]) continue;
int left = b+1;
int right = nums.size()-1;
while(left < right) {
if(left < right &&(long)nums[a] + nums[b] + nums[left] +nums[right] > target) right--;
else if(left < right && (long)nums[a] + nums[b] + nums[left] +nums[right] < target) left++;
else{
result.push_back(vector<int>{nums[a], nums[b], 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;
}
};