LeetCode刷题记录——15三数之和

LeetCode刷题记录——15三数之和

一 题目记录:

给你一个包含n个整数的数组 nums,判断nums中是否存在三个元素a、b、c,使得 a + b + c = 0 ?,请你找出所有的满足条件不重复的三元组

【注】答案中不可以包含重复的三元组

示例:

  • 给定数组 nums = [-1, 0, 1, 2, -1, -4],
    
    满足要求的三元组集合为:
    [
      [-1, 0, 1],
      [-1, -1, 2]
    ]
    

二 思路:

  • 关键点在于去重,去除重复的计算。先讲数组排序,然后在按顺序遍历数组,设置两个指针,对数组的两端同时进行搜索,只有达到目标才进行下一次的循环

  • 使用左右指针指向nums[i]后面的两端,判断nums[L]+nums[R]+nums[i]是否等于0,

    • 如果 nums[i]大于 0,则三数之和必然无法等于 00,结束循环
    • 如果 nums[i] == nums[i-1],则说明该数字重复,会导致结果重复,所以应该跳过
    • 当 sum == 0 时,nums[L]== nums[L+1] 则会导致结果重复,应该跳过,L++
      当 sum == 0 时,nums[R]== nums[R-1] 则会导致结果重复,应该跳过,R–
  • 以下代码第一种会出现超时的情况,第二种不会

  • 代码:

    • //出现超时情况
      class Solution {
      public:
          vector<vector<int>> threeSum(vector<int>& nums) {
              int len = nums.size();
              vector<vector<int>> ret;
              if(len < 3)
                  return ret;
              sort(nums.begin(),nums.end());
              int sum = 0;
              int p1=0,p2=0;//分别对应L和R
              for(int i = 0;i<len;i++){
                  if(nums[i]>0)
                      break;
                  if( i>0 && nums[i] == nums[i-1])        //去重
                      continue;
                  p1 = i+1;//设置双指针
                  p2 = len-1; 
                  while(p1 <p2){
                      sum = nums[i] + nums[p1] + nums[p2];
                      if(sum == 0){
                          vector<int> vtemp{nums[i],nums[p1],nums[p2]};
                          ret.push_back(vtemp);
                          vtemp.clear();
                          //去重
                          while(p1 < p2 &&nums[p1] == nums[p1+1])
                              p1++;
                          while(p1<p2 && nums[p2] == nums[p2 - 1])
                              p2++;
                      }
                      else if(sum<0)
                          p1++;
                      else if(sum>0)
                          p2--;
                  }
              }
          return ret;
          }
      };
      
    • class Solution {
      public:
          vector<vector<int> > threeSum(vector<int>& nums) {
              vector<vector<int> > ret;
              int len = nums.size();
              sort(nums.begin(),nums.end());//sort the input
              for(int i=0;i<len-2;i++){
                  //find the tripe for each nums[i]
                  // j1 and j2 log the index of the other two numbers
                  if(i ==0 ||(i>0 && nums[i] != nums[i-1])){
                      int p1 = i+1, p2 = len-1; // set two pointers
                      while(p1 < p2){
                          if(nums[p1] + nums[p2] < -nums[i]){
                              p1++;
                          }else if(nums[p1] + nums[p2] == -nums[i]){
                              if(p1 == i+1){
                                  vector<int > vtemp{nums[i], nums[p1], nums[p2]};
                                  ret.push_back(vtemp);
                                  vtemp.clear();
      
                              }else if(nums[p1] != nums[p1-1]){
                                  vector<int > vtemp{nums[i], nums[p1], nums[p2]};
                                  ret.push_back(vtemp);
                                  vtemp.clear();
      
                              }
                              p1++,p2--;
                          }else{
                               p2--;
                          }
                      }
                  }
      
      
              }
              return ret;
      
          }
      };
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值