LeetCode(1)三数之和为0

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37293461/article/details/84035466

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

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

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]

一,暴力法,直接用三个指针遍历数组

public static List<List<Integer>> threeSum(int[] nums)
        {
            Arrays.sort(nums);           //数组排序
            List<List<Integer>> outList = new ArrayList<List<Integer>>();     //定义一个ArrayList线性表
            for (int i = 0; i < nums.length; i++)
            {
                if ((i > 0 && nums[i] == nums[i - 1]))      //去重,做判断。如果符合条件就返回循环,对应的i直接跳过
                    continue;                     
                for (int j = i + 1; j < nums.length; j++)
                {
                    if ((j > i + 1 && nums[j] == nums[j - 1]))       //去重
                        continue;                        
                    for (int k = j + 1; k < nums.length; k++)
                    {
                        if ((k > j + 1 && nums[k] == nums[k - 1]))     //去重
                            continue;
                        if ((nums[i] + nums[j] + nums[k] == 0))        //判断和为零
                        {
                            outList.add(Arrays.asList(nums[i],nums[j],nums[k]));   //添加到ArrayList中
                            break;
                        }
                    }
                }
            }
            return outList;        //返回找到的符合条件的数组
        } 

最终测试代码在这里插入图片描述

这时我们发现,超时了。仔细分析我们知道循环太多了,而且都是三个for嵌套,这样直接导致了时间复杂度飙升
那么我们想办法降低下时间复杂度。

二,头尾指针法
方法一是三个指针依次数组后面移,那么我们试下头尾加指针,缩小范围来减小时间复杂度

public static List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        for (int i = 0; i + 2 < nums.length; i++)
        {
            if (i > 0 && nums[i] == nums[i - 1]) {     //去重
                continue;
            }
            int j = i + 1, k = nums.length - 1;
            int target = -nums[i];
            while (j < k)
            {
                if (nums[j] + nums[k] == target)
                {
                    res.add(Arrays.asList(nums[i], nums[j], nums[k]));   //添加到新的数组
                    j++;  k--;
                    while (j < k && nums[j] == nums[j - 1]) j++;  //  各循环起始点不需要判断重复
                    while (j < k && nums[k] == nums[k + 1]) k--;  //  各循环起始点不需要判断重复
                } else if (nums[j] + nums[k] > target)
                   {
                       k--;         //k左移
                    } else {
                       j++;         //j右移
                   }
            }
        }
        return res;
    }

有问题欢迎留言哦

参考:

https://leetcode.com/problems/3sum/discuss/?orderBy=recent_activity

猜你喜欢

转载自blog.csdn.net/m0_37293461/article/details/84035466