探索三数之和:算法Hot100系列解密!
2023-10-26 13:00:23
三数之和:踏上算法进阶之路
欢迎来到算法Hot100系列!今天,我们一起探索激动人心的三数之和问题,踏上算法进阶之路。准备好了吗?那就出发吧!
三数之和:概念剖析
三数之和问题看似简单,但蕴藏着丰富的算法知识。给定一个整数数组nums
,找出所有满足a + b + c = 0
的三元组(a, b, c)
,其中a
、b
和c
均来自nums
。
比如,对于nums = [-1, 0, 1, 2, -1, -4]
,存在以下三元组:
[-1, -1, 2]
[-1, 0, 1]
算法策略:双指针法
解决三数之和问题的经典算法策略是双指针法。这种方法利用两个指针从数组的两端向中间移动,动态调整三数之和,高效且巧妙。
具体步骤如下:
- 排序数组
nums
,以方便快速查找目标和。 - 固定第一个指针
i
,代表a
。 - 用两个指针
j
和k
从i + 1
和n - 1
向中间移动,代表b
和c
。 - 计算三数之和
sum
:sum = nums[i] + nums[j] + nums[k]
. - 根据
sum
与目标和0
比较,调整j
或k
指针:- 如果
sum < 0
,j
向右移动(j++
),增大三数之和。 - 如果
sum > 0
,k
向左移动(k--
),减小三数之和。 - 如果
sum == 0
,找到一个三元组,将j
和k
指针向右移动,继续查找重复的三元组。
- 如果
- 重复步骤3-5,直到
j
和k
指针相遇。
代码实现:
def threeSum(nums):
# 排序数组
nums.sort()
result = []
# 固定第一个指针
for i in range(len(nums) - 2):
# 跳过重复的a
if i > 0 and nums[i] == nums[i - 1]:
continue
# 设置双指针
j, k = i + 1, len(nums) - 1
# 双指针向中间移动
while j < k:
# 计算三数之和
sum = nums[i] + nums[j] + nums[k]
# 根据sum调整指针
if sum < 0:
j += 1
elif sum > 0:
k -= 1
else:
# 找到三元组,保存结果
result.append([nums[i], nums[j], nums[k]])
# 跳过重复的b和c
while j < k and nums[j] == nums[j + 1]:
j += 1
while j < k and nums[k] == nums[k - 1]:
k -= 1
# 移动指针继续查找
j += 1
k -= 1
return result
时间复杂度分析
双指针法的时间复杂度为O(n^2)
,其中n
是数组nums
的长度。这是因为:
- 排序数组需要
O(nlogn)
时间。 - 对于每个元素
a
(需要n
次),使用双指针在剩下的n - 1
个元素中查找三元组,需要O(n)
时间。
拓展:四数之和及更多
三数之和问题是算法Hot100中的基础问题,类似的拓展问题还有四数之和、五数之和等。这些问题都可以通过双指针法或更高级的算法策略求解。
结语
探索三数之和问题,我们不仅收获了解决问题的算法策略,更领略了算法之美。双指针法巧妙地利用数组有序性,高效地解决了复杂的问题。
算法的学习永无止境,让我们继续前行,在算法Hot100系列中不断探索,解锁更多算法奥秘,成就编程高手之路!
常见问题解答
- 三数之和问题有什么实际应用?
三数之和问题在计算机科学和工程领域有着广泛的应用,例如:
- 物理中的质点碰撞
- 化学中的反应平衡
- 经济学中的市场均衡
- 双指针法是如何工作的?
双指针法利用两个指针从数组的两端向中间移动,动态调整三数之和,高效且巧妙。当三数之和小于目标和时,右指针向右移动;当三数之和大于目标和时,左指针向左移动。当三数之和等于目标和时,找到一个三元组。
- 除了双指针法,还有哪些解决三数之和问题的方法?
除了双指针法,还有其他解决三数之和问题的方法,例如:
- 哈希表法
- 排序 + 二分查找法
- 三数之和问题的时间复杂度是多少?
双指针法的时间复杂度为O(n^2)
,其中n
是数组nums
的长度。
- 如何优化双指针法的性能?
优化双指针法的性能可以从以下几个方面入手:
- 预处理数组,将元素按值分组
- 使用哈希表存储已经计算过的三数之和
- 提前终止算法,当找不到满足条件的三元组时