返回

最接近的三数之和:轻松掌握LeetCode经典算法题

后端

征服 LeetCode 第 16 题:最接近的三数之和

在编程的世界中,算法题就像磨刀石,磨砺着我们的思维,提升着我们的编码能力。今天,让我们一起征服 LeetCode 的第 16 题——最接近的三数之和,一道中等难度的算法题。

题意

给定一个整数数组 nums 和一个整数 target,要求我们找到数组中三个数,使得它们的和最接近 target

乍一看,这道题似乎有些难度,但别担心,只要我们掌握了解题思路和技巧,一切都会变得简单起来。

解题思路

第一步:对数组进行排序

排序后的数组有什么好处呢?我们可以通过双指针法来遍历数组,快速找到满足题意的三个数。

什么是双指针法?

双指针法是一种常见的算法技巧,它使用两个指针来遍历数组,一个指针从数组的开头开始,另一个指针从数组的末尾开始。这两个指针同时向数组中间移动,并在移动过程中比较元素的值。当两个指针相遇或超过时,遍历结束。

在我们的例子中,我们可以使用双指针法来遍历排序后的数组。当两个指针相遇时,我们已经找到了两个数,它们的和与 target 的差值最小。如果我们需要找到三个数,我们可以继续移动其中一个指针,直到找到第三个数,使得三个数的和与 target 的差值最小。

代码实现

def threeSumClosest(nums, target):
  """
  :type nums: List[int]
  :type target: int
  :rtype: int
  """
  # Sort the array
  nums.sort()

  # Initialize the closest sum and the difference
  closest_sum = float('inf')
  diff = float('inf')

  # Iterate over the array using two pointers
  for i in range(len(nums) - 2):
    # Skip duplicate elements
    if i > 0 and nums[i] == nums[i - 1]:
      continue

    # Set the left and right pointers
    left, right = i + 1, len(nums) - 1

    # Move the pointers until they meet or cross
    while left < right:
      # Calculate the current sum
      current_sum = nums[i] + nums[left] + nums[right]

      # Update the closest sum and the difference
      if abs(current_sum - target) < diff:
        closest_sum = current_sum
        diff = abs(current_sum - target)

      # Move the left or right pointer
      if current_sum < target:
        left += 1
      else:
        right -= 1

  # Return the closest sum
  return closest_sum

总结

掌握了解题思路和技巧后,LeetCode 第 16 题就变得简单多了。通过对数组进行排序和使用双指针法,我们可以快速找到满足题意的三个数。

常见问题解答

  1. 为什么需要对数组进行排序?

排序后的数组可以方便我们使用双指针法。通过对数组进行排序,我们可以快速找到满足题意的三个数。

  1. 如何设置双指针法?

一个指针从数组的开头开始,另一个指针从数组的末尾开始。这两个指针同时向数组中间移动,并在移动过程中比较元素的值。

  1. 如何更新 closest_sum 和 diff?

当我们找到三个数的和与 target 的差值更小的组合时,我们就更新 closest_sum 和 diff 的值。

  1. 为什么需要使用 while 循环来移动指针?

我们使用 while 循环来移动指针,直到它们相遇或超过。这样,我们可以确保找到满足题意的三个数。

  1. 为什么需要跳过重复元素?

跳过重复元素可以防止我们找到重复的三个数组合。