剑指offer(3)3 sum问题

由于提前做过了4 sum问题,3sum就很明显了

题目

给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组。
注意:
三元组(a、b、c、d)中的元素必须按非降序排列。(即a≤b≤c)
解集中不能包含重复的三元组。
例如,给定的数组 S = {-1 0 1 2 -1 -4},↵↵ 解集为:↵ (-1, 0, 1)↵ (-1, -1, 2)

题目解析

同样是获得所有的组合,找到符合3个元素相加等于0的组合。

解题思路

  • 首先进行排序
  • 其次,外层循环控制一个元素移动
  • 然后,通过双指针收缩,获取不同的组合进行判断

实例代码

public ArrayList<ArrayList<Integer>> threeSum(int[] num) {

       //数字组合必须排序
       Arrays.sort(num);
       ArrayList<ArrayList<Integer>> lists=new ArrayList<>();
       //i循环向右
       for (int i=0;i<num.length-2;i++)
       {
           //第一次控制i重复,也就是第一个元素重复场景
           //如果重复跳出本次循环
           if (i > 0 && num[i] == num[i - 1]) {
               continue;
           }

               //begin位置为j后边,end为最后一个元素
               int begin=i+1,end=num.length-1;
               //对begin,end双指针进行收缩
               while (begin<end) {
                   //大于给定值 end--
                   if (num[i] + num[begin] + num[end] > 0)
                       end--;
                       //小于给定值begin++
                   else if (num[i] + num[begin] + num[end] < 0)
                       begin++;

                       //等于给定值,就进行添加
                   else if (num[i] +  num[begin] + num[end] == 0) {				//需要在这里进行初始化,否则进行元素覆盖
                       ArrayList<Integer> list = new ArrayList<>();
                       list.add(num[i]);
                       //此组合符合,同时begin,end继续收缩
                       list.add(num[begin++]);
                       list.add(num[end--]);
                       lists.add(list);
                       //第二次去重,将begin相同的去除
                       while (begin < end && num[begin -1] == num[begin]) {
                           begin++;
                       }
                       //第三次去重,将end重复去掉
                       while (begin < end && num[end +1] == num[end]) {
                           end--;
                       }
                   }
               }


           }
       return lists;
   }

重要的就是对元素进行去重操作,去重操作应发生在每一层循环。
在我的算法栏目中含有类似题目及解法。
题目来源牛客网。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值