454.四数相加II
题目:454. 四数相加 II
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
//先算a+b, 再算c+d, 时间复杂度O(n^2)
int ans = 0;
unordered_map<int,int> m;
for(int x : nums1){
for(int y : nums2){
m[x+y] += 1;
}
}
for(int z : nums3){
for(int k : nums4){
if(m.find(0 - z - k) != m.end()){
ans += m[0 - z - k];
}
}
}
return ans;
}
};
383. 赎金信
题目:383. 赎金信
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
unordered_map<char,int> m;
for(char x : magazine){
m[x]++;
}
for(char y : ransomNote){
m[y]--;
}
for(auto z : m){
if(z.second < 0) return false;
}
return true;
}
};
15. 三数之和
题目:15. 三数之和
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int> > ans;
sort(nums.begin(),nums.end());
unordered_map<int,int> m;
for(int i = 0; i < nums.size(); ++i){
if(nums[i] > 0) continue;
if(i>0 && nums[i] == nums[i - 1]) continue; //a去重
//双指针法
int left = i + 1;
int right = nums.size() - 1;
while(left < right){
if(nums[i] + nums[left] + nums[right] > 0) right--;
else if(nums[i] + nums[left] + nums[right] < 0) left++;
else {
ans.push_back({nums[i],nums[left],nums[right]});
//对b和c去重
while(left < right && nums[left] == nums[left + 1]) left++;
while(left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
}
}
}
return ans;
}
};
18. 四数之和
题目:18. 四数之和
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int> > ans;
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[i] + nums[j] > target && nums[i] + nums[j] >= 0) {
break;
}
//去重操作
if(j > i + 1 && nums[j] == nums[j - 1]) continue;
int left = j + 1;
int right = nums.size() - 1;
while(right > left){
//防止溢出转化为long
if((long long) nums[i] + nums[j] + nums[left] + nums[right] > target) right--;
else if((long long) nums[i] + nums[j] + nums[left] + nums[right] < target) left++;
else{
ans.push_back({nums[i],nums[j],nums[left],nums[right]});
//去重操作
while(right > left && nums[left] == nums[left + 1]) left++;
while(right > left && nums[right] == nums[right - 1]) right--;
left++;
right--;
}
}
}
}
return ans;
}
};
总结
题型:map的使用,三数之和(双指针法),四数之和
技巧:注意map的遍历,有时候排个序更容易解决问题
双指针在数字,链表,字符串中都有应用,遇事不决想想双指针,可以将算法优化一个数量级!
考虑数据溢出问题