返回

LeetCode斩“75”题:红橙黄绿勇闯江湖

后端

颜色分类:算法技巧巧解 LeetCode 第 75 题

颜色分类简介

在现实生活中,我们经常需要对物品进行分类,比如按照颜色对衣服进行分类。在算法领域,也有一个类似的问题,称为颜色分类,其目的是将一组数字按照特定顺序重新排列。

LeetCode 第 75 题

LeetCode 第 75 题正是让你实现颜色分类。给定一个包含 0、1 和 2 的数字数组,你的任务是将这些数字按从小到大重新排列,即所有的 0 放在最前面,所有的 1 放在中间,所有的 2 放在最后。

朴素解法:遍历和插入

一种最直观的方法是对数组进行遍历,然后根据每个元素的值来决定将其放在哪个位置。

def color_sort_naive(nums):
  for i in range(len(nums)):
    if nums[i] == 0:
      nums.pop(i)
      nums.insert(0, 0)
    elif nums[i] == 1:
      nums.pop(i)
      nums.insert(len(nums) // 2, 1)
    else:
      nums.pop(i)
      nums.append(2)

  return nums

这种方法虽然能够正确分类,但效率低下,因为每次都需要删除和重新插入元素,会浪费大量时间。

优化解法:双指针法

为了提高效率,我们可以使用双指针法。双指针法是一种常见的算法技巧,可以让我们在数组中快速找到特定元素或位置。

在颜色分类问题中,我们可以使用两个指针:left 指针指向数组开头,right 指针指向数组末尾。然后,我们从数组开头和末尾同时向中间遍历。

当我们遇到 0 时,我们将它与 left 指针指向的元素交换,然后将 left 指针向后移动一位。

当我们遇到 2 时,我们将它与 right 指针指向的元素交换,然后将 right 指针向前移动一位。

当我们遇到 1 时,我们直接将指针向后移动一位。

def color_sort_optimal(nums):
  left, right = 0, len(nums) - 1

  while left < right:
    if nums[left] == 0:
      nums[left], nums[right] = nums[right], nums[left]
      right -= 1
    elif nums[left] == 2:
      nums[left], nums[right] = nums[right], nums[left]
      left += 1
    else:
      left += 1

  return nums

这种优化解法的复杂度为 O(n),其中 n 是数组的长度,空间复杂度为 O(1),大大提高了效率。

总结

颜色分类是一种经典的算法问题,可以通过多种方法解决。通过朴素解法和双指针法,我们展示了如何从直观解法过渡到更有效率的解决方案。

常见问题解答

  1. 为什么双指针法比朴素解法更高效?
    答:双指针法不需要删除和重新插入元素,因此避免了不必要的开销。

  2. 双指针法如何处理数组中可能出现的重复元素?
    答:双指针法不会受到重复元素的影响,因为它只关注元素的值,而不考虑其位置。

  3. 是否还有其他解决颜色分类问题的方法?
    答:是的,还有其他方法,例如荷兰国旗问题算法。

  4. 颜色分类问题在现实世界中有何应用?
    答:颜色分类问题在数据排序和处理、图像处理和机器学习等领域都有应用。

  5. 如何提高解决算法问题的技能?
    答:通过练习、研究算法原理和技巧,并尝试解决不同的问题来提高解决算法问题的技能。