返回

数组中的三数之和:LeetCode 难题剖析

前端

今日,我将带领大家深入探索 LeetCode 中一道极具挑战性的题目——“三数之和”。我们将从题目分析入手,探究多种解法,并提供详尽的代码示例,帮助你攻克这道难题。

题目分析

给定一个整数数组 nums,找出其中三个数之和为 0 的所有唯一三元组。注意:答案中不可以包含重复的三元组。

示例:

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

解法

解法一:暴力法(通过不了,只提供思路)

暴力法的思路很简单,就是枚举所有可能的三元组,然后检查它们是否满足条件。这种方法的时间复杂度为 O(n³),其中 n 是数组的长度。由于时间复杂度太高,这种方法在 LeetCode 中无法通过。

解法二:Set 法

Set 法利用了集合的特性,可以快速查找元素。具体的做法是:

  1. 将数组中的所有元素放入一个集合中。
  2. 遍历数组中的每个元素,然后计算它的相反数。
  3. 对于每个元素及其相反数,查找集合中是否存在第三个元素,使其和为 0。
  4. 如果找到了这样的第三个元素,则将这三个元素组成一个三元组添加到结果中。

Set 法的时间复杂度为 O(n²),空间复杂度为 O(n)。

解法三:指针法

指针法是一种更加高效的解法,它利用了数组是有序这一特性。具体的做法是:

  1. 排序数组。
  2. 使用三个指针 i、j 和 k,分别指向数组的开头、中间和结尾。
  3. 如果 nums[i] + nums[j] + nums[k] < 0,则说明 k 指针指向的元素太大了,需要向左移动。
  4. 如果 nums[i] + nums[j] + nums[k] > 0,则说明 j 指针指向的元素太小了,需要向右移动。
  5. 如果 nums[i] + nums[j] + nums[k] = 0,则找到了一个三元组,将这三个元素添加到结果中。
  6. 重复步骤 3-5,直到 j 指针指向 k 指针。

指针法的时间复杂度为 O(n²),空间复杂度为 O(1)。

优化

优化解法二

解法二可以通过使用哈希表来优化,哈希表的查找时间复杂度为 O(1)。具体做法是:

  1. 将数组中的所有元素放入一个哈希表中,键为元素本身,值为 true。
  2. 遍历数组中的每个元素,然后计算它的相反数。
  3. 对于每个元素及其相反数,查找哈希表中是否存在第三个元素,使其和为 0。
  4. 如果找到了这样的第三个元素,则将这三个元素组成一个三元组添加到结果中。

优化解法三

解法三可以通过使用双指针法来优化。具体做法是:

  1. 排序数组。
  2. 使用两个指针 i 和 j,分别指向数组的开头和结尾。
  3. 如果 nums[i] + nums[j] < 0,则说明 j 指针指向的元素太小了,需要向右移动。
  4. 如果 nums[i] + nums[j] > 0,则说明 i 指针指向的元素太大了,需要向左移动。
  5. 如果 nums[i] + nums[j] = 0,则找到了一个三元组,将这三个元素添加到结果中。
  6. 重复步骤 3-5,直到 i 指针指向 j 指针。

总结

通过对 LeetCode 中“三数之和”难题的剖析,我们了解了暴力法、Set 法和指针法三种解法。指针法是最优解法,它的时间复杂度为 O(n²),空间复杂度为 O(1)。通过优化,还可以进一步提升解法的效率。