力扣算法题三数之和的解法与分析

力扣算法题三数之和

15.三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,
使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。

这道算法题我苦思冥想了很久,始终不得解,看了题解才豁然开朗,感叹自己还是个算法小白。
此算法主要运用到的思想是排序+双指针,但是如何去重才是关键。
排序是为了能使用双指针,对于双指针,我本来是用for循环重新遍历一遍的,但是其实不然,使用while(L<R)去循环会很好的防止指针越界,也不用多做条件去判断。

思路

标签:数组遍历
首先对数组进行排序,排序后固定一个数 nums[i]nums[i]nums[i],再使用左右指针指向 nums[i]nums[i]nums[i]后面的两端,数字分别为 nums[L]nums[L]nums[L] 和 nums[R]nums[R]nums[R],计算三个数的和 sumsumsum 判断是否满足为 000,满足则添加进结果集
如果 nums[i]nums[i]nums[i]大于 000,则三数之和必然无法等于 000,结束循环
如果 nums[i]nums[i]nums[i] == nums[i−1]nums[i-1]nums[i−1],则说明该数字重复,会导致结果重复,所以应该跳过
当 sumsumsum == 000 时,nums[L]nums[L]nums[L] == nums[L+1]nums[L+1]nums[L+1] 则会导致结果重复,应该跳过,L++L++L++
当 sumsumsum == 000 时,nums[R]nums[R]nums[R] == nums[R−1]nums[R-1]nums[R−1] 则会导致结果重复,应该跳过,R−−R--R−−
时间复杂度:O(n2)O(n^2)O(n2),nnn 为数组长度

以下是我的烂代码

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> zeronums = new ArrayList<>();

        if(nums.length<3||nums==null){
            return zeronums;
        }
      
        //排序
        Arrays.sort(nums); // 排序
        
        int leftp,rightp;


        for (int i=0;i<nums.length;i++) {
            leftp = i+1;
            rightp = nums.length-1;
            if(nums[i]>0){
                break;
            }

            if(i>0&&nums[i]==nums[i-1]){
                continue;
            }

            while (leftp<rightp){
            //for (int j=0;j<nums.length-i-1;j++) {
                int sum = nums[leftp]+nums[rightp]+nums[i];
                if(sum==0){

                    List<Integer> zeronum = new ArrayList<>();
                    zeronum.add(nums[i]);
                    zeronum.add(nums[leftp]);
                    zeronum.add(nums[rightp]);
                    zeronums.add(zeronum);
                    //去重
                    while (leftp<rightp && nums[leftp] == nums[leftp+1]) leftp++;
                    while (leftp<rightp && nums[rightp] == nums[rightp-1]) rightp--;
                    leftp++;
                    rightp--;

                }
                if(sum>0){
                    rightp--;
                }else if (sum<0){
                    leftp++;
                }




            }


        }
        return zeronums;

    }
}

题解思路来自
作者:guanpengchn
链接:https://leetcode-cn.com/problems/3sum/solution/hua-jie-suan-fa-15-san-shu-zhi-he-by-guanpengchn/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值