Bootstrap

Leetcode 每日一题 15.三数之和

引言

在算法的世界里,有些问题虽然看似简单,但却是锻炼算法思维的绝佳练习。今天,我们将深入探讨一个在面试中经常出现的问题——“三数之和”问题。这个问题不仅考验我们对数组操作的熟练程度,还考察我们如何利用数组的特性来优化算法。本文将详细介绍如何使用排序和双指针法解决“三数之和”问题,并提供Java语言的实现。

问题背景

给定一个整数数组 nums,我们的任务是找出所有和为 0 且不重复的三元组。这意味着我们需要找出数组中的三个不同索引 ijk,使得 nums[i] + nums[j] + nums[k] = 0。这个问题实际上是在询问,如何通过选择三个元素来使它们的和为零。

输入输出规范

输入: 整数数组 nums,一个包含整数的数组。

输出: 整数三元组的列表 result,表示所有和为 0 且不重复的三元组。

示例解析

示例 1: 输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]] 解释: nums[0] + nums[1] + nums[4] = (-1) + 0 + 1 = 0nums[0] + nums[3] + nums[5] = (-1) + 2 + (-1) = 0。 不同的三元组是 [-1,0,1][-1,-1,2]。 注意,输出的顺序和三元组的顺序并不重要。

示例 2: 输入:nums = [0,1,1] 输出:[] 解释:唯一可能的三元组和不为 0。

示例 3: 输入:nums = [0,0,0] 输出:[[0,0,0]] 解释:唯一可能的三元组和为 0。

算法策略

排序和双指针法是解决此类问题的常用策略。我们首先对数组进行排序,然后使用两个指针分别从排序后的数组的两端开始,通过调整这两个指针的位置来寻找能够构成和为0的三个数。

Java代码实现

 

java

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums); // 对数组进行排序
        List<List<Integer>> result = new ArrayList<>();
        for (int i = 0; i < nums.length - 2; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) continue; // 跳过重复的元素
            int left = i + 1;
            int right = nums.length - 1;
            while (left < right) {
                int sum = nums[i] + nums[left] + nums[right];
                if (sum < 0) {
                    left++; // 需要更大的数
                } else if (sum > 0) {
                    right--; // 需要更小的数
                } else {
                    result.add(Arrays.asList(nums[i], nums[left], nums[right])); // 找到和为0的三元组
                    while (left < right && nums[left] == nums[left + 1]) left++; // 跳过重复的元素
                    while (left < right && nums[right] == nums[right - 1]) right--; // 跳过重复的元素
                    left++;
                    right--;
                }
            }
        }
        return result; // 返回所有和为0的三元组
    }
}

复杂度分析

时间复杂度: O(n^2),其中 n 是数组 nums 的长度。排序的时间复杂度为 O(nlogn),双指针法的时间复杂度为 O(n^2)。

空间复杂度: O(1),只需要常量级的额外空间来存储结果。

通过图片

LeetCode地址

15. 三数之和 - 力扣(LeetCode)

结语

通过排序和双指针法,我们不仅解决了“三数之和”问题,还展示了如何利用数组的特性来优化算法。这种方法的时间复杂度和空间复杂度都非常低,适用于处理大规模数据集。希望这篇文章能够帮助你深入理解排序和双指针法,并将其应用到实际问题中。如果你有任何疑问或想要进一步探讨,欢迎在评论区交流。同时,如果你觉得这篇文章对你有帮助,不妨点个赞或者分享给需要的朋友。让我们一起进步,一起成长!

;