阅读 165

Leetcode15 三数之和

Leetcode15 三数之和

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

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

示例 1:

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

输出:[[-1,-1,2],[-1,0,1]]


思路分析:

三数之和为0,即分以下三种情况:

1. 三个0

2. 两个相等的数+一个不相等的数

3. 三个不相等的数


需要考虑到的情况:


传入数组数组长度是否大于3

因为输出数组为有序的,是否排序后处理数组会更方便

三数之和要等于0,那么排序后的数组,当nums[0]>0,输出[]

输出的数组为不重复的三元组,就需要考虑其去重问题(重点)。

去重主要解决因两个或两个以上相等的值导致无效遍历的问题。


解法:

方法一:采用哈希表去重


//时间复杂度太高,超出时间限制

public List<List<Integer>> threeSum1(int[] nums) {

        Arrays.sort(nums);

        List<Integer> list;

        Set<List<Integer>> set=new HashSet<List<Integer>>();

        List<List<Integer>> lList=new ArrayList<List<Integer>>();

        for(int i=0;i<nums.length-2;i++){

            for(int j=i+1;j<nums.length-1;j++){

                for(int k=j+1;k<nums.length;k++){

                    if(nums[i]+nums[j]+nums[k]==0){

                        

                        list=new ArrayList<Integer>();

                        list.add(nums[i]);

                        list.add(nums[j]);

                        list.add(nums[k]);

                        set.add(list);

                    }

                }

            }

        }

        lList.addAll(set);

        return lList;

    }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

方法二:采用双指针法



public List<List<Integer>> threeSum(int[] nums) {

        List<Integer> list;

        List<List<Integer>> lList=new ArrayList<List<Integer>>();

        //如果数组长度小于3,直接返回空

        if(nums.length<3){

            return lList;

        }

        //对数组先进行排序

        Arrays.sort(nums);        

        for(int i=0;i<nums.length;i++){

            //如果第一个元素的值大于0,直接返回

            if(nums[i]>0){

                return lList;

            }

         

            

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

                continue;

            }


            int left=i+1;

            int right=nums.length-1;

            while(left<right){

                if(nums[i]+nums[left]+nums[right]>0){

                    right--;

                }else if(nums[i]+nums[left]+nums[right]<0){

                    left++;

                }else{

                    list=new ArrayList<Integer>();

                    list.add(nums[i]);

                    list.add(nums[left]);

                    list.add(nums[right]);

                    lList.add(list);

                    //与26行,27行去重类似,该行如果放在添加进arrayList之前,可能会出现遗漏{0,0,0}的情况

                    //比如[0,0,0,0,0,1,2]

                    while(left<right&&nums[right]==nums[right-1]){

                        right--;

                    }

                    while(left<right&&nums[left]==nums[left+1]){

                        left++;

                    }


                    //得到答案后,i不变,通过双指针相向移动,保证三数之和可能为0

                    right--;

                    left++;

                }

            }

        }

        return lList;

    }

————————————————

版权声明:本文为CSDN博主「tomcat333333」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/thorf/article/details/114708440


文章分类
后端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐