15. 三数之和) https://leetcode.cn/problems/3sum/[...">
美文网首页
15. 三数之和

15. 三数之和

作者: 王侦 | 来源:发表于2022-09-25 08:04 被阅读0次

    题目地址(3sum/">15. 三数之和)

    https://leetcode.cn/problems/3sum/

    题目描述

    给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
    
    你返回所有和为 0 且不重复的三元组。
    
    注意:答案中不可以包含重复的三元组。
    

    前置知识

    • 双指针法

    公司

    • 暂无

    思路

    • 双指针法

    关键点

    • 1)去重,需要排序然后才方便判断,第一个数和第二个数都需要判断重复,我这里两个去重方法都放在最后
    • 2)最精妙之处,还是双指针法,j = i + 1, k = n - 1(末尾)
      • 情况1.nums[j] + nums[k] < target,此时只需要j++即可
      • 情况2.nums[j] + nums[k] > target,此时k--即可
      • 关键问题,k--后,要不要还原k到n-1,答案是不用,因为数组已经排过序了,j++后,想要j,k位置两数之和为target,k必然是一直--

    代码

    • 语言支持:Java

    Java Code:

    
    class Solution {
        public List<List<Integer>> threeSum(int[] nums) {
            int n = nums.length;
            if (null == nums || n < 3) {
                return null;
            }
            // 依次将数组的第一个元素作为target,然后在剩下的数组寻找两个之和为target的数
            List<List<Integer>> result = new ArrayList<>();
            // 排序是为了去重方便
            Arrays.sort(nums);
            for (int i = 0; i < n - 2;)  {
                // 双指针法
                int j = i + 1;
                int k = n - 1;
                int target = - nums[i];
                while (j < k) {
                    while (j < k && nums[j] + nums[k] > target) {
                        k--;
                    }
                    // 这里不能少了j < k,否则当j == k时,会一个位置取两次
                    if (j < k && nums[j] + nums[k] == target) {
                        result.add(new ArrayList<>(Arrays.asList(nums[i], nums[j], nums[k])));  
                    }
                    j++;
                    // 跳过重复的j
                    while (j < k && nums[j] == nums[j - 1]) {
                        j++;
                    }    
                }
                i++;
                while (i < n - 2 && nums[i] == nums[i - 1]) {
                    i++;
                }
            }
            return result;
        }
    }
    
    

    Go code:

    func threeSum(nums []int) [][]int {
        if (nums == nil || len(nums) < 3) {
            return nil
        }
        n := len(nums)
        // sort标准库
        sort.Ints(nums)
        // 使用make,才能append
        result := make([][]int, 0)
        for i := 0; i < n - 2; {
            j, k, target := i + 1, n - 1, - nums[i]
            for j < k {
                for j < k && nums[j] + nums[k] > target {
                    k--
                }
    
                if j < k && nums[j] + nums[k] == target {
                    // append是builtin标准库
                    result = append(result, []int{nums[i], nums[j], nums[k]})
                }
    
                j++
                for j < k && nums[j] == nums[j - 1] {
                    j++
                } 
            }
            i++
            for i < n - 2 && nums[i] == nums[i - 1] {
                i++
            }
        }
        return result
    }
    

    复杂度分析

    令 n 为数组长度。

    • 时间复杂度:O(n^2)
    • 空间复杂度:就是排序的空间复杂度,如果需要复制,则是O(n)

    相关文章

      网友评论

          本文标题:15. 三数之和

          本文链接:https://www.haomeiwen.com/subject/syczortx.html