数据结构与算法之 leetcode 数组三数之和 双指针 + 去重

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


数组三数之和:双指针与去重技巧在LeetCode中的应用

在LeetCode等编程竞赛和面试中,数组三数之和问题是一个经典且具有挑战性的题目。该问题要求在给定一个整数数组中,找出所有和为特定值的三元组。这个问题不仅考察了我们对数组操作的理解,还考验了我们的算法设计和优化能力。本文将围绕双指针和去重技巧,深入探讨如何解决数组三数之和问题。

问题分析

数组三数之和问题可以描述如下:

输入:一个整数数组 `nums` 和一个整数 `target`。

输出:返回一个包含所有和为 `target` 的三元组的列表。三元组中的元素必须按升序排列,且每个元素在原数组中不能重复出现。

示例:

python

nums = [1, 2, 3, 4, 5]


target = 7


输出:[[1, 2, 4], [1, 3, 3], [2, 2, 3]]


解决方案

双指针法

双指针法是解决数组三数之和问题的关键。其基本思想是将数组排序,然后使用两个指针分别指向数组的头部和尾部,通过移动指针来寻找满足条件的三元组。

步骤:

1. 对数组 `nums` 进行排序。

2. 初始化两个指针 `left` 和 `right`,分别指向数组的头部和尾部。

3. 遍历数组,对于每个元素 `nums[i]`,将 `left` 指针指向 `i+1`,将 `right` 指针指向数组的尾部。

4. 当 `left` 指针小于 `right` 指针时,计算当前三个元素的和 `nums[i] + nums[left] + nums[right]`。

- 如果和等于 `target`,则将当前三元组添加到结果列表中,并将 `left` 和 `right` 指针分别向右移动一位,以避免重复的三元组。

- 如果和小于 `target`,则将 `left` 指针向右移动一位,以增加和的值。

- 如果和大于 `target`,则将 `right` 指针向左移动一位,以减小和的值。

5. 重复步骤 4,直到 `left` 指针大于等于 `right` 指针。

去重技巧

在双指针法的基础上,为了确保结果中的三元组不重复,我们需要在添加三元组到结果列表时进行去重处理。

步骤:

1. 在添加三元组到结果列表之前,检查列表中是否已经存在相同的三元组。

2. 如果存在,则跳过当前三元组,否则将其添加到结果列表中。

代码实现

以下是一个使用双指针和去重技巧解决数组三数之和问题的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


left, right = i + 1, len(nums) - 1


while left < right:


current_sum = nums[i] + nums[left] + nums[right]


if current_sum == target:


result.append([nums[i], nums[left], nums[right]])


left += 1


right -= 1


while left < right and nums[left] == nums[left - 1]:


left += 1


while left < right and nums[right] == nums[right + 1]:


right -= 1


elif current_sum < target:


left += 1


else:


right -= 1


return result


总结

数组三数之和问题是一个典型的算法问题,通过双指针和去重技巧,我们可以有效地解决它。在实际应用中,我们需要根据具体问题调整算法的复杂度和效率。通过不断练习和总结,我们可以提高自己的算法设计能力,为未来的挑战做好准备。