返回

三数之和:高效算法与刷题实战

前端

三数之和算法剖析

三数之和算法旨在找出数组中三个元素之和为0的三元组,并避免重复。算法的核心在于巧妙运用双指针技巧,通过遍历数组并不断调整指针位置,有效缩小搜索范围,提高算法效率。

算法步骤

  1. 排序数组 :首先将数组进行排序,以便利用有序性进行优化。
  2. 双指针遍历 :设置两个指针leftright,分别指向数组的开头和末尾。
  3. 计算三数之和 :计算当前leftright和中间元素之和,即sum = nums[left] + nums[mid] + nums[right]
  4. 调整指针位置 :根据sum与0的大小关系调整指针位置,以缩小搜索范围。
  5. 记录结果 :当sum = 0时,记录当前三元组并更新指针位置,继续寻找下一个三元组。
  6. 重复步骤3-5 :重复上述步骤,直到遍历完整个数组。

时间复杂度分析

三数之和算法的时间复杂度为O(n^2),其中n为数组的长度。排序数组需要O(nlogn)的时间,而双指针遍历则需要O(n^2)的时间。

LeetCode刷题实战

让我们以LeetCode经典的三数之和题目为例,亲身体验算法的应用。

题目

给你一个包含n个整数的数组nums,判断nums中是否存在三个元素abc,使得a + b + c = 0?请你找出所有和为0且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例

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

解题思路

我们可以使用上述的三数之和算法来解决这个问题。首先对数组进行排序,然后使用双指针技巧遍历数组,计算三数之和,并记录符合条件的三元组。

代码实现

def threeSum(nums):
    """
    :type nums: List[int]
    :rtype: List[List[int]]
    """
    # 排序数组
    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:
            sum = nums[i] + nums[left] + nums[right]

            # 三数之和为0,记录结果并更新指针位置
            if sum == 0:
                result.append([nums[i], nums[left], nums[right]])

                # 跳过重复元素
                while left < right and nums[left] == nums[left + 1]:
                    left += 1
                while left < right and nums[right] == nums[right - 1]:
                    right -= 1

                # 更新指针位置
                left += 1
                right -= 1

            # 三数之和大于0,右指针左移
            elif sum > 0:
                right -= 1
            # 三数之和小于0,左指针右移
            else:
                left += 1

    return result

结语

三数之和算法是LeetCode的经典题目之一,也是算法学习和编程实践的良好范例。通过本文的详细讲解和刷题实战,相信你已经对算法有了更深入的理解。继续努力,在算法的世界中不断探索,收获更多知识和成就感!