力扣15.三数之和

Problem: 15. 三数之和

题目描述

在这里插入图片描述在这里插入图片描述

思路

我们将问题分解为两个待解决的问题:

1.如何实现不重复
2.如何更高效的实现输出和为0且不重复的三元组

1.如何实现不重复:

1.我们首先对数组进行一个排序,然后再实现三重循环。
2.在三重循环的大框架下,我们先利用第一层循环枚举a,在第二层循环中用来枚举b同时确保第二重循环枚举到的元素不小于当前第一层循环枚举的元素,同理第三层循环用来枚举c同时确保第三层循环枚举到的元素不小于第二层枚举到的元素

但我们应该注意:

**每一层循环中,相邻两次枚举的元素不能相同,否则也会造成重复!!!**例如:
[0, 1, 2 , 2, 2, 3]
当枚举出一个(0,1,2)后,第二层循环向后又会得到(0,1,2)
所以我们应该通过判断nums[i] 与 nums[i - 1]相等于否移动到于相邻元素第一个不相等的下标位置

如何更高效的实现输出和为0且不重复的三元组:

1.我们在实现第一层循环后立即选定当前的nums[first]的负数作为比较目标值(target)在开始第二层循环时我们定义third 指向数组的末尾,然后开始第三层循环运用双指针的思想保证second < third,对nums[second] + nums[third] 与target的大小进行比较,若nums[second] + nums[third] > target则表明third处的值大了,需要让已经排好序的数组中的third–
2.虽然我们是使用的三重循环的大框架,但是第二层和第三层时同时进行的,所以最后还是O(N^2)的复杂度

复杂度

时间复杂度:

O ( n 2 ) O(n^2) O(n2);其中 n n n为数组nums的大小

空间复杂度:

O ( 1 ) O(1) O(1)

Code

class Solution {
    /**
     * Sum of three numbers
     *
     * @param nums Given array
     * @return List<List < Integer>>
     */
    public List<List<Integer>> threeSum(int[] nums) {
        int length = nums.length;
        // Sort the array
        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList<>();
        // Enumerate a
        for (int first = 0; first < length; first++) {
            //first cannot be repeated
            if (first > 0 && nums[first] == nums[first - 1]) {
                continue;
            }
            // Select a target
            int target = -nums[first];
            int third = length - 1;
            // Enumerate b
            for (int second = first + 1; second < length; second++) {
                //second Cannot be repeated
                if (second > first + 1 && nums[second] == nums[second - 1]) {
                    continue;
                }
                while (second < third && nums[second] + nums[third] > target) {
                    third--;
                }
                // Exit when equal
                if (second == third) {
                    break;
                }
                // Add appropriate elements
                if (nums[third] + nums[second] == target) {
                    List<Integer> temp = new ArrayList<>();
                    temp.add(nums[first]);
                    temp.add(nums[second]);
                    temp.add(nums[third]);
                    res.add(temp);
                }
            }
        }
        return res;
    }
}
  • 27
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值