454. 四数相加 II
题目描述:454. 四数相加 II
注意事项:
- 理解在什么时候使用map
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int, int> m;
for(int a : nums1){
for(int b : nums2){
m[a + b]++;
}
}
int count = 0;
for(int c : nums3){
for(int d : nums4){
auto iter = m.find(0 - c - d);
if(iter != m.end()){
count += m[0 - c - d];
}
}
}
return count;
}
};
383. 赎金信
题目链接:383. 赎金信
注意事项:
- 刚开始使用这种遍历方式,注意变量类型
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
unordered_map<char, int> m;
for(char i : magazine){
m[i]++;
}
for(char j : ransomNote){
auto iter = m.find(j);
if(iter == m.end()){
return false;
}
if(--m[j] < 0){
return false;
}
}
return true;
}
};
15. 三数之和
题目链接:15. 三数之和
注意事项:
- 考虑去重
第一个错误版本:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> r;
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size(); i++){
int left = i + 1;
int right = nums.size() - 1;
while(left < right){
int sum = nums[i] + nums[left] + nums[right];
if(sum == 0){
r.push_back({nums[i], nums[left], nums[right]});
break;
}else if(sum > 0){
right--;
}else{
left++;
}
}
}
return r;
}
};
提交后的效果:
修改后:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> r;
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size(); i++){
if(i > 0 && nums[i] == nums[i - 1]){ //对i位置的数字略过重复值
continue;
}
int left = i + 1;
int right = nums.size() - 1;
while(left < right){
int sum = nums[i] + nums[left] + nums[right];
if(sum == 0){
r.push_back({nums[i], nums[left], nums[right]});
while(left < right && nums[left] == nums[left + 1])left++; //对left位置的数字略过重复值
while(left < right && nums[right] == nums[right - 1])right--; //对right位置的数字略过重复值
left++; //移动到不是重复的位置
right--;
}else if(sum > 0){
right--;
}else{
left++;
}
}
}
return r;
}
};
18. 四数之和
题目链接:18. 四数之和
注意事项:
- 多个数相加考虑溢出的情况
- 第二层的循环时,判断略过重复值的J的起始值为i+1
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> r;
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size(); i++){
if(i > 0 && nums[i] == nums[i - 1]){ //对i位置的数字略过重复值
continue;
}
for(int j = i + 1; j < nums.size(); j++){
if(j > i + 1 && nums[j] == nums[j - 1]){ //对j位置的数字略过重复值,注意从i+1开始
continue;
}
int left = j + 1;
int right = nums.size() - 1;
//cout << left << " " << right << endl;
while(left < right){
long sum = (long)nums[i] + nums[j] + nums[left] + nums[right]; //考虑溢出的情况
if(sum == target){
r.push_back({nums[i], nums[j], nums[left], nums[right]});
while(left < right && nums[left] == nums[left + 1])left++;
while(left < right && nums[right] == nums[right - 1])right--;
left++; //移动到不是重复的位置
right--;
}else if(sum > target){
right--;
}else{
left++;
}
}
}
}
return r;
}
};