Leetcode 学习之路

Leetcode 学习之路 015 三数之和

前言

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

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

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

输入:nums = []
输出:[]

输入:nums = [0]
输出:[]

一、解题思路

       根据题目描述,最简单的方式是使用暴力循环的算法,对于三个元素,每个都将数组从头到尾循环一边,将得到的三个元素相加进行判断。但是这种做法使时间复杂度为 O ( N 3 ) O(N^3) O(N3).在Leetcode上提交也会显示超出时间限制。为了简化时间复杂度可以使用双指针的方式。首先将数组按照升序排列,对于第一个元素,我们选择遍历的数组的方式来寻找。对于第二个和第三个元素,设置左右指针分别指向数组的左右端点,然后分两种情况进行讨论。
       第一种情况,将左指针向右移动:

nums[first]+nums[second]+nums[third]<0

       第二种情况,将右指针向左移动:

nums[first]+nums[second]+nums[third]>0

       因为数组是按照升序进行排列的,所以不会出现遗漏的情况

二、JAVA 代码

List<List<Integer>> result=new ArrayList<List<Integer>>();
        if (nums.length<=2||nums==null) return result;
        Arrays.sort(nums);
        for (int first=0;first<nums.length;first++){
            if (first>0&&nums[first]==nums[first-1]) continue;
            int second=first+1,target=-nums[first];
            int third=nums.length-1;
            while (second<third){
                if (nums[second]+nums[third]>target){

                    while (third>second&&nums[third-1]==nums[third])
                        third--;
                    third--;
                }
                else if (nums[second]+nums[third]<target){
                    while (second<third&&nums[second+1]==nums[second])
                        second++;
                    second++;
                }
                else{
                    List<Integer> temp=new ArrayList<>();
                    temp.add(nums[first]);
                    temp.add(nums[second]);
                    temp.add(nums[third]);
                    result.add(temp);
                    while (second<third&&nums[third-1]==nums[third])
                        third--;
                    third--;
                }
            }
        }
        return result;

总结

       这道题除了巩固双指针的用法,还需要注意,对数组元素查找的前一步是对数组进行排序,这样可以提高查找效率。此外,对数组进行遍历也要考虑越界情况,可以在循环中设置if判断语句当下标>1或者<右端点是进行运算。最后,在左右指针的移动算法中,每一次移动都需要考虑左指针是否小于右指针,例如最内层的三个while循环,将second<right去掉的话,一些特殊情况就会报错,例如[0,0,0,0]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值