[leetcode刷题之旅]15.三数之和

1.题目解析

题目链接

在这里插入图片描述

这道题的简单版:2sum

题目的要求有三:

  1. 确定一个数c,并找到另外两个数a,b,使得a+b=-c
  2. 确定的三元组不能有重复,即我们需要对数据中重复的数据进行处理
  3. 能否选择同一个数(即对应的下标的两个数或三个数)确定一个等式(这个是我自己提出的疑问不知道是不是我没理清题目的意思,解法中默认这种情况是不成立的)

2.实现代码

public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> lists = new LinkedList<>();
        if(nums.length >= 3) {
            Arrays.sort(nums);
            for (int mark = 0; mark < nums.length - 2; mark ++) {
                if (nums[mark] > 0) break;
                if (mark > 0 && nums[mark] == nums[mark - 1]) continue;
                for (int i = mark + 1, j = nums.length - 1; i < j; ) {
                    int sum = nums[mark] + nums[j] + nums[i];
                    if (sum == 0) {
                        lists.add(Arrays.asList(nums[mark],nums[i],nums[j]));
                        while(i < j && nums[i + 1] == nums[i]) i++;
                        while(i < j && nums[j - 1] == nums[j]) j--;
                        i++;
                        j--;
                    } else if (sum > 0)
                        j--;
                    else
                        i++;
                }
            }
        }
        return lists;
    }

对数据进行排序的原因:因为题目要求不允许结果数组有重复,那么就需要我们在代码中对有可能出现的重复情况进行处理,重复性的检验方法有很多,但大部分都要新建一个数据结构对数据进行归纳,因此我选择对数组进行排序来优化重复性检验的过程。调用JAVA提供的库函数Arrays.sort()就可以排序了。

接下来就是算法的核心思路:

  1. 首先固定一个数c(这里使用遍历的方法,扫描数组)
  2. 确定两个指针a,b。a从c+1开始,b从nums.length-1开始向中间扫描。(这里a不从0开始扫描的原因是确定c时就已经把前面的情况考虑到了)
  3. 确定范围的方法:
    • a+b+c>0,说明a+b的结果大了,那么较大数需要减小,即b向左移
    • a+b+c<0,说明a+b的结果小了,那么较小数需要增大,即a向右移
    • a+b+c=0,说明是正确的结果,调用Arrays.asList()产生新链表合并到结果中,然后让a,b继续向中间移动,因为还有可能会有别的情况。
    • 在a,b移动的过程中还应该对出现重复的数字筛除
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值