四数相加
题目解答
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int count = 0;
unordered_map<int, int> umap;
for (int i : nums1)
for (int j : nums2)
umap[i + j]++;
for(int m:nums3)
for (int n : nums4)
if (umap.find(0 - m - n) != umap.end()) count += umap[0 - m - n];
return count;
}
};
该题目是同样熟悉哈希表的题目,但是如果不看题解,还真写不出来。
赎金信
题目解答
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int arr[26]={0};
for(char ch:magazine) arr[ch-'a']++;
for(char ch:ransomNote){
arr[ch-'a']--;
if(arr[ch-'a']<0) return false;
}
return true;
}
};
该题目同样是使用哈希表,较为简单。
三数之和
题目解答(添加了自己的一些代码,以便能在编译器上运行)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
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++) {
int a = nums[i];
if (a > 0) return result;
//去重 1
if (i > 0 && nums[i] == nums[i - 1]) continue;
int left = i + 1;
int right = nums.size() - 1;
while (left < right) {
if (nums[left] + nums[right] + a > 0) right--;
else if (nums[left] + nums[right] + a < 0) left++;
else {
result.push_back({ a,nums[left],nums[right] });
//去重 2
while (left < right && nums[right] == nums[right - 1]) right--;
while (left < right && nums[left] == nums[left + 1])left++;
right--;
left++;
}
}
}
return result;
}
};
int main() {
Solution s;
vector<int> nums;
int a;
cin >> a;
nums.push_back(a);
while (cin.get() != '\n') {
cin >> a;
nums.push_back(a);
}
//for (int i : nums) cout << i << " ";
cout << endl << "-------------------------------------------------------------------------------" << endl;
vector<vector<int>> result = s.threeSum(nums);
for (vector<int> veit : result) {
for (int it : veit) cout << it << '\t';
cout << endl;
}
return 0;
}
解题心得(题目解法实在是想不到,直接就看了卡子哥的题解了)
1、整体思路就是先排序,然后使用三个指针,第一个指针用for循环遍历,第二个指针和第三个指针放在第一个指针后面所有元组的首段和末端,然后再通过while(left<right)的方式遍历。
2、题目难的就是去重。
- 对第一个指针指向的元组去重,要使用:
if (i > 0 && nums[i] == nums[i - 1]) continue;
如果使用:
if (nums[i] == nums[i + 1]) continue;
那么就会漏掉有相同的元素组成为‘0’的情况。
- 对于left和right指针的去重必须是先找到结果再去重,要不然就会漏掉对应的结果。
3、补充:
该题目可以进行剪枝操作:
if (a > 0) return result;
四数之和
题目解答
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
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++) {
long long temp = target - nums[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++) {
long long a = nums[j];
if (a > temp && a > 0) break;
if (j > i + 1 && nums[j] == nums[j - 1]) continue;
int left = j + 1;
int right = nums.size() - 1;
while(left < right){
if ((long long)nums[left] + nums[right] + a > temp)right--;
else if ((long long)nums[left] + nums[right] + a < temp)left++;
else {
result.push_back({ nums[i],(int)a,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;
}
};
int main() {
Solution s;
vector<int> nums;
int a;
cin >> a;
nums.push_back(a);
while (cin.get() != '\n') {
cin >> a;
nums.push_back(a);
}
int target;
cin >> target;
cout << endl << "-------------------------------------------------------------------------------" << endl;
vector<vector<int>> result = s.fourSum(nums, target);
for (vector<int> veit : result) {
for (int i : veit) {
cout << i << " ";
}
cout << endl;
}
return 0;
}
解题心得
1、题目的变量数据类型要用 long long 的,因为数据范围的原因。
2、题目和三数之和大体上差不多,只是要多用一个for循环。
3、然后题目的修剪枝叶要加上一个大于零的的条件,因为如[-5,-4,-3,1],target=-11;就要要求-5不仅要大于-11,而且还要大于零,要不然就会报错的。