454.四数相加II
看了一下视频,自己写出来了
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int,int> map;
int count=0;
for(int i=0;i<nums1.size();i++){
for(int j=0;j<nums2.size();j++){
map[ nums1[i]+nums2[j] ]++;
}
}
for(int k=0;k<nums3.size();k++){
for(int l=0;l<nums2.size();l++){
if(map.find( 0-nums3[k]-nums4[l])!=map.end()){
count=count+map[0-nums3[k]-nums4[l]];
}
}
}
return count;
}
};
// map哈希结构
383. 赎金信
用数组,比较容易
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int Hash[26]={0};
for(int ch:magazine){
Hash[ch-'a']++;
}
for(int ch:ransomNote){
Hash[ch-'a']--;
if(Hash[ch-'a']<0){
return false;
}
}
return true;
}
};
// 数组哈希结构
15. 三数之和
看了视频讲解,有点不好琢磨
(哈希法
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
// 三数之和——哈希表法
vector<vector<int>> result;
sort(nums.begin(), nums.end());
// 找出a + b + c = 0
// a = nums[i], b = nums[j], c = -(a + b)
for (int i = 0; i < nums.size(); i++) {
// 排序之后如果第一个元素已经大于零,那么不可能凑成三元组
if (nums[i] > 0) {
break;
}
if (i > 0 && nums[i] == nums[i - 1]) { //三元组元素a去重
continue;
}
// 可以理解为第一个定住了,后面就是两数之和的问题
unordered_set<int> set;
for (int j = i + 1; j < nums.size(); j++) {
if (j > i + 2//3
&& nums[j] == nums[j-1]
&& nums[j-1] == nums[j-2])
//&& nums[j-2] == nums[j-3])
{ // 三元组元素b去重
// 主要是避免后面有两个的值满足target的情况出现多次,如果不限制两个的话,如果是1个,就会漏情况,如果>=4个,出现两组重复,事实上3个也应该没问题,单个巴掌拍不响,验证了一下,确实可以;
continue;
}
int c = 0 - (nums[i] + nums[j]);
if (set.find(c) != set.end()) {
result.push_back({nums[i], nums[j], c});
set.erase(c);// 三元组元素c去重
} else {
set.insert(nums[j]);
}
}
}
return result;
}
};
( 双指针法
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
// 三数之和——循环+双指针
sort(nums.begin(),nums.end());
vector<vector<int>> result; //二维创建
for(int i=0;i<nums.size();i++){
if(nums[i]>0){
return result;
}
if(i>0 && nums[i]==nums[i-1]){
continue;
}
int left=i+1,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{
result.push_back(vector<int>{nums[i], nums[left], nums[right]});
// while放后面也是为了防止两个重复值不被统计的情况
while (right > left && nums[right] == nums[right - 1]){
right--;
}
while (right > left && nums[left] == nums[left + 1]){
left++;
}
left++;
right--;
}
}
}
return result;
}
};
18. 四数之和
自己写出来了,很多细节要注意,调试好费劲
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){
return result;
} // 剪枝
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,right=nums.size()-1;
while(left<right){
if((long)nums[a]+nums[b]+nums[left]+nums[right]>target){
right--;
}
else if ((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(right > left && nums[left]==nums[left+1]){
left++;
}
while(right > left && nums[right]==nums[right-1]){
right--;
}
left++;
right--;
}
}
}
}
return result;
}
};