返回

使用巧妙的排序和双指针,轻松破解三数之和难题

后端

在编程的世界里,算法就像乐曲中的音符,组合在一起奏响解决问题的交响曲。三数之和问题,恰似一曲美妙的协奏曲,考验着程序员的算法功底。今天,我们将踏上这趟算法之旅,使用排序和双指针的旋律,破解三数之和的难题。

乐章一:排序的序曲

算法之旅的第一步,让我们为数组排序。排序就像给一盘散乱的珠子整理顺序,将它们从低到高排列。通过排序,我们可以轻松找到数组中的最小值和最大值,为后续算法的展开铺平道路。

乐章二:双指针的协奏

排序的序曲完成后,双指针将登场献艺。双指针如同乐谱上的两个音符,它们相互配合,在数组中穿梭滑动。一个指针指向数组的开头,另一个指针指向数组的末尾。这两个指针就像两支探照灯,共同寻找满足三数之和条件的三元组。

当双指针相遇时,它们会根据当前的和值做出判断。如果和值小于目标和,则左指针向右移动,增大和值;如果和值大于目标和,则右指针向左移动,减小和值。这种双指针的协奏,奏响了三数之和的求解旋律。

乐章三:算法的变奏

双指针的协奏曲并不只有一种形式,它还有着变奏的余地。一种常见的变奏是固定一个指针,另一个指针在剩余的数组中滑动。这种变奏可以进一步优化算法的效率,尤其是在数组元素较多的时候。

乐章四:示例代码的华彩乐章

为了让算法的旋律更加清晰,我们不妨用示例代码来演奏这首乐曲:

def three_sum(nums):
  # 排序数组
  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]

      # 判断和值
      if sum < target_sum:
        # 和值小于目标和,左指针右移
        left += 1
      elif sum > target_sum:
        # 和值大于目标和,右指针左移
        right -= 1
      else:
        # 和值等于目标和,找到三元组
        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

  # 返回结果
  return result

尾声:总结的余音

三数之和算法的破解之旅,是一场思维的盛宴,也是一场算法的较量。通过巧妙地使用排序和双指针,我们可以轻松解决这一难题。这种算法不仅适用于三数之和,更可以应用于其他类似的问题,在编程的世界里谱写出更多的动人乐章。