返回
数组中的三数之和:LeetCode 难题剖析
前端
2023-10-01 11:59:52
今日,我将带领大家深入探索 LeetCode 中一道极具挑战性的题目——“三数之和”。我们将从题目分析入手,探究多种解法,并提供详尽的代码示例,帮助你攻克这道难题。
题目分析
给定一个整数数组 nums,找出其中三个数之和为 0 的所有唯一三元组。注意:答案中不可以包含重复的三元组。
示例:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解法
解法一:暴力法(通过不了,只提供思路)
暴力法的思路很简单,就是枚举所有可能的三元组,然后检查它们是否满足条件。这种方法的时间复杂度为 O(n³),其中 n 是数组的长度。由于时间复杂度太高,这种方法在 LeetCode 中无法通过。
解法二:Set 法
Set 法利用了集合的特性,可以快速查找元素。具体的做法是:
- 将数组中的所有元素放入一个集合中。
- 遍历数组中的每个元素,然后计算它的相反数。
- 对于每个元素及其相反数,查找集合中是否存在第三个元素,使其和为 0。
- 如果找到了这样的第三个元素,则将这三个元素组成一个三元组添加到结果中。
Set 法的时间复杂度为 O(n²),空间复杂度为 O(n)。
解法三:指针法
指针法是一种更加高效的解法,它利用了数组是有序这一特性。具体的做法是:
- 排序数组。
- 使用三个指针 i、j 和 k,分别指向数组的开头、中间和结尾。
- 如果 nums[i] + nums[j] + nums[k] < 0,则说明 k 指针指向的元素太大了,需要向左移动。
- 如果 nums[i] + nums[j] + nums[k] > 0,则说明 j 指针指向的元素太小了,需要向右移动。
- 如果 nums[i] + nums[j] + nums[k] = 0,则找到了一个三元组,将这三个元素添加到结果中。
- 重复步骤 3-5,直到 j 指针指向 k 指针。
指针法的时间复杂度为 O(n²),空间复杂度为 O(1)。
优化
优化解法二
解法二可以通过使用哈希表来优化,哈希表的查找时间复杂度为 O(1)。具体做法是:
- 将数组中的所有元素放入一个哈希表中,键为元素本身,值为 true。
- 遍历数组中的每个元素,然后计算它的相反数。
- 对于每个元素及其相反数,查找哈希表中是否存在第三个元素,使其和为 0。
- 如果找到了这样的第三个元素,则将这三个元素组成一个三元组添加到结果中。
优化解法三
解法三可以通过使用双指针法来优化。具体做法是:
- 排序数组。
- 使用两个指针 i 和 j,分别指向数组的开头和结尾。
- 如果 nums[i] + nums[j] < 0,则说明 j 指针指向的元素太小了,需要向右移动。
- 如果 nums[i] + nums[j] > 0,则说明 i 指针指向的元素太大了,需要向左移动。
- 如果 nums[i] + nums[j] = 0,则找到了一个三元组,将这三个元素添加到结果中。
- 重复步骤 3-5,直到 i 指针指向 j 指针。
总结
通过对 LeetCode 中“三数之和”难题的剖析,我们了解了暴力法、Set 法和指针法三种解法。指针法是最优解法,它的时间复杂度为 O(n²),空间复杂度为 O(1)。通过优化,还可以进一步提升解法的效率。