c++_三数之和

本题目可以选用两种方法做

1. 暴力解法

2.排序+双指针

这里着重讲第二种方法

力扣15. 三数之和 - 力扣(LeetCode)

 写题思路:

将原数组排序,这样的话,每个筛选出来的,不会存在组合相同顺序不同。

1.定义i 作为第一个数的下标 使用while循环(i!=nums.size()-2)  为什么-2? 因为最多为倒数第三个

2.第一层循环的处理,如果nuns[i]>0 那么后面的j和k相加就不可能为0 所以直接return 

  long long l=static_cast<long long >(nums[left]); 为防止溢出

3. 第二层循环,如果和小于0 那么吧left++ 如果大于0 right--,如果恰好满足 先判断下一个是不是和当前的数一样大小,如果一样大,left++,因为如果不加会出现重复问题,右边也是同理。

下面第一层循环也是这个道理,如果nums[i+1] ==nums[i] 会产生重复解

 

class Solution {

public:

    vector<vector<int>> threeSum(vector<int>& nums) {

       if(nums.size()<3)

        return {};

       vector<vector<int> > ans;

       sort(nums.begin(),nums.end());

       int i=0;

   

   while(i<nums.size()-2)

 {

      if(nums[i]>0)

        return ans; 

      int left=i+1,rigjt=nums.size()-1;

      while(left<rigjt)

      {

        long long l=static_cast<long long >(nums[left]);

        long long r=static_cast<long long >(nums[rigjt]);

        long long p=static_cast<long long >(nums[i]);

      if(l+r>0-p)

        rigjt--;

      else if(l+r<0-p)

        left++;

      else if(l+r+p==0)

      {

      ans.push_back({nums[i],nums[left],nums[rigjt]});

      while(left<rigjt&&nums[left]==nums[left+1])

       left++;

      while(left<rigjt&&nums[rigjt]==nums[rigjt-1])

       rigjt--;

    

       left++;

       rigjt--;

      } 


 

      }

   while(i<nums.size()-2&&nums[i]==nums[i+1])

    i++;

    i++;

}   

    //-1 -1 0 1

    return ans;

    }

};

 暴力做法在下面 三层循环

 

class Solution {

public:

    vector<vector<int>> threeSum(vector<int>& nums) {

    vector<vector<int>> target;

    //sort(nums.begin(),nums.end());

    for(int i=0;i<nums.size()-2;i++)

    {

      for(int j=i+1;j<nums.size()-1;j++)

      {

       for(int k=j+1;k<nums.size();k++)

       {

        if(nums[i]+nums[j]+nums[k]!=0)

          continue;

        int p=0;

         for(;p<target.size();p++)

         {

           if(target[p][0]==nums[i]&&target[p][1]==nums[j]&&target[p][2]==nums[k])

           {

              break;

           }

           

         }

         if(p==target.size())   

         target.push_back({nums[i],nums[j],nums[k]});

       }


 

      }

    }

   return target;

    }

};

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值