数据结构与算法之 leetcode 数组三数之和算法 排序后双指针

数据结构与算法阿木 发布于 4 天前 2 次阅读


数组三数之和算法(排序后双指针)详解与实现

在LeetCode等编程竞赛平台中,数组三数之和问题是一个经典且具有挑战性的算法题目。该问题要求在给定一个整数数组中,找出所有和为特定值的三元组。本文将围绕这一主题,详细介绍排序后双指针算法的原理、实现方法以及优化技巧。

问题分析

假设我们有一个整数数组 `nums` 和一个目标值 `target`,我们的任务是找到所有满足以下条件的三元组 `(nums[i], nums[j], nums[k])`:

1. `i`, `j`, `k` 互不相同。

2. `nums[i] + nums[j] + nums[k] == target`。

为了解决这个问题,我们可以采用排序后双指针的方法。

排序后双指针算法原理

排序后双指针算法的核心思想是:首先对数组进行排序,然后使用两个指针分别从数组的两端开始遍历,通过调整指针的位置来寻找满足条件的三元组。

步骤分析

1. 排序:对数组 `nums` 进行排序,这样我们可以根据数组的顺序来调整指针的位置。

2. 遍历:使用一个指针 `i` 从数组的第一个元素开始遍历,`i` 的取值范围是 `0` 到 `n-3`(其中 `n` 是数组的长度)。

3. 双指针:对于每个 `i`,设置两个指针 `j` 和 `k`,其中 `j` 初始值为 `i+1`,`k` 初始值为 `n-1`。

4. 调整指针:

- 如果 `nums[i] + nums[j] + nums[k] == target`,则找到了一个满足条件的三元组,将其添加到结果集中,并将 `j` 和 `k` 分别向前和向后移动一位,继续寻找下一个三元组。

- 如果 `nums[i] + nums[j] + nums[k] < target`,则说明当前的三元组和小于目标值,需要将 `j` 向前移动一位,以增加和的值。

- 如果 `nums[i] + nums[j] + nums[k] > target`,则说明当前的三元组和大于目标值,需要将 `k` 向后移动一位,以减小和的值。

5. 重复步骤 3 和 4,直到指针 `i` 遍历完整个数组。

代码实现

下面是使用排序后双指针算法解决数组三数之和问题的Python代码实现:

python

def threeSum(nums, target):


nums.sort() 对数组进行排序


result = []


for i in range(len(nums) - 2):


if i > 0 and nums[i] == nums[i - 1]: 跳过重复的元素


continue


j, k = i + 1, len(nums) - 1


while j < k:


current_sum = nums[i] + nums[j] + nums[k]


if current_sum == target:


result.append([nums[i], nums[j], nums[k]])


j += 1


k -= 1


while j < k and nums[j] == nums[j - 1]: 跳过重复的元素


j += 1


while j < k and nums[k] == nums[k + 1]: 跳过重复的元素


k -= 1


elif current_sum < target:


j += 1


else:


k -= 1


return result


优化技巧

1. 跳过重复元素:在遍历过程中,如果发现当前元素与上一个元素相同,则跳过,以避免重复的三元组。

2. 提前终止:如果当前的三元组和已经大于目标值,则无需继续遍历 `k` 指针,因为随着 `k` 的减小,和的值只会更大。

3. 使用哈希表:如果题目要求返回每个三元组的唯一组合,可以使用哈希表来存储已经找到的三元组,以避免重复。

总结

数组三数之和问题是一个典型的算法问题,通过排序后双指针算法可以有效地解决。本文详细介绍了该算法的原理、实现方法以及优化技巧,希望对读者有所帮助。在实际编程中,我们可以根据具体问题调整算法的细节,以达到最佳的性能。