LeetCode每日一题:三数之和

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

注意:答案中不可以包含重复的三元组。

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

思路:本文提供的排序+双指针思路
1.对数组进行升序排序。
2.对于数组中任意一个值,假设其索引为k,len为数组长度,那么我们需要在(k,len)内利用双指针判读是否存在两个数与索引为K的值和为0。
3.由于是排序后的数组,当三数之和大于0,说明最大值较大,将最右边指针左移一位,反之说明最小值较小,最左边指针右移一位。

下面是算法流程和一些边界的条件
1.判断nums的长度为空或者长度小于3直接返回
2.排序数组
3.遍历数组
当nums[k]>0时,因为是排序数组,因此后面不存在可以使三数和为0的情况,直接跳出循环。
当K>len-3时,说明K后面不存在3个数,也跳出循环
当nums[k]=nums[k-1]时,避免存在相同值,k++,跳过后续操作
4.双指针选择符合的两个数
令左指针L=k+1,右指针R=len-1,当L<R,执行循环
当nums[L]+nums[R]+nums[k]=0时 添加到列表中,并且判断左边界和有边界下一个值是否和当前值相同,若相同跳过下一个值。寻找新的解
当nums[L]+nums[R]+nums[k]>0时 nums[R]过大 右指针左移
当nums[L]+nums[R]+nums[k]<0时 nums[L] 过小 左指针右移

public List<List<Integer>> threeSum(int[] nums) {
        List list=new ArrayList<List>();
        if(nums.length<3)return list;  //当数组为空或者长度小于3 返回空
        
        Arrays.sort(nums);
        for(int index=0;index<=nums.length-3&&nums[index]<=0;index++){
            if(index>0&&nums[index]==nums[index-1])//与上一个值相同 避免重复 跳过
                 continue;
            int l=index+1;
            int r=nums.length-1;
            while(l<r)
            {
                if(nums[l]+nums[r]+nums[index]==0){
                     List t=new ArrayList<Integer>();
                        t.add(nums[index]);
                        t.add(nums[l]);
                        t.add(nums[r]);
                        list.add(t);
                        while(l<r&&nums[l]==nums[l+1])l++;//下一个位置值相同,跳过
                        while(l<r&&nums[r]==nums[r-1])r--;//同上
                        l++;
                        r--;
                }
                else if(nums[index]+nums[l]+nums[r]>0)r--;
                else l++;
                }
        }
        return list;
    }
发布了28 篇原创文章 · 获赞 0 · 访问量 373

猜你喜欢

转载自blog.csdn.net/qq_40053995/article/details/104695419