454. 四数相加 II
class Solution {
public:
/*[1,2]
[-2,-1]
[-1,2]
[0,2]*/
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
map<int,int> res;
//map<int,int> res_3_4;
int count=0;
int sizen=nums1.size();
//先求1,2想加的结果,并将结果存到res里;
int sum1;
//int count=0;
for(int i=0;i<sizen;i++){
for(int j=0;j<sizen;j++){
sum1=nums1[i]+nums2[j];
//res.insert(sum1);
res[sum1]++;//这里对语法不太理解
}
}
for(int k=0;k<sizen;k++){
for(int l=0;l<sizen;l++){
int target=0-(nums3[k]+nums4[l]);
if(res.find(target)!=res.end())
{
count=count+res[target];
}
}
}
return count;
}
};
/-----------------------------------------------------------------------------------------------/
15.三数之和
通过看教程得知,知道题用哈希算法比较麻烦,因为涉及到去重,双指针法比较快
"双指针"法其实是三指针,既i/left/right如图
i从0往后遍历,i每次更新,left都指向i+1,right指向末尾;
这道题的关键,1.其实是如何去重;具体看代码随想录的教程;
还有2.要先对数组进行排序才可以;
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
sort(nums.begin(),nums.end());//将nums由小到大排序
for(int i=0;i<nums.size();i++){
int left=i+1;
int right=nums.size()-1;
if(nums[0]>0) return res;
//思考:if的逻辑判断顺序是如何的?如果i>0不通过的话,还继续后面的吗
//答:经测试,不运行
if(i>0&&nums[i]==nums[i-1]){
continue;//它的逻辑是,如果nums[i]和前面的想等了,就不用在进行下面各种判断了
}
while(left<right)
{
int sum=nums[i]+nums[left]+nums[right];
if(sum>0)//right是最大的所以如果大了,要向里移动
{
right--;
}else if(sum<0)
{
left++;
}else{
res.push_back(vector<int>{nums[i],nums[left],nums[right]});
while(left<right&&nums[left]==nums[left+1]) left++;
while(left<right&&nums[right]==nums[right-1]) right--;
//要理解这个地方
right--;
left++;
}
//i++;
}
}
return res;
}
};
存疑:
1.去重的逻辑还是不明白啊!!!
/-----------------------------------------------------------------------------------------------/
第18题. 四数之和
大体的思路和框架与上题目15.三树之和一样,就多了去重和剪枝的细节;
具体还是参考代码随想录把;
284 / 292 个通过测试用例
状态:执行出错
提交时间:2 分钟前
执行出错信息:
Line 29: Char 54: runtime error: signed integer overflow: 2000000000 + 1000000000 cannot be represented in type ‘int’ (solution.cpp)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:38:54
最后执行的输入:
[0,0,0,1000000000,1000000000,1000000000,1000000000]
1000000000
//出了问题,应该是由于这一句
long sum=nums[k]+nums[i]+nums[left]+nums[right];
改成
if((long)nums[k]+nums[i]+nums[left]+nums[right]>target)
感悟:
1.从哪些角度去思考,思考什么问题,才能让自己短时间内提高更快??
比如,为什么用这个方法,他的优势劣势是什么? 能不能举一反三?
他的核心或者基本理论是什么?
2.还要理清思路,为什么用这些工具.这种思路?
收获:
1.增强了对双指针(去重复)的理解;
待完成:
1.三数之和的图解;