代码随想录算法训练营第7天 |哈希

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.三数之和的图解;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值