LeetCode题目75:颜色分类【python】

简介: LeetCode题目75:颜色分类【python】

作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。

会一些的技术:数据分析、算法、SQL、大数据相关、python

欢迎加入社区:码上找工作

作者专栏每日更新:

LeetCode解锁1000题: 打怪升级之旅

python数据分析可视化:企业实战案例

python源码解读

备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级

题目描述

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。我们使用整数 012 分别表示红色、白色和蓝色。

输入格式
  • nums:一个整数数组,包含 0(红色)、1(白色)、2(蓝色)。
输出格式
  • 不需要返回任何内容,需将 nums 数组按上述规则排序。

示例

示例 1
输入: nums = [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
示例 2
输入: nums = [2,0,1]
输出: [0,1,2]

方法一:计数排序

解题步骤
  1. 计数:遍历数组,计算 012 的数量。
  2. 重写数组:根据各个数字的数量,重新填充数组。
完整的规范代码
def sortColors(nums):
    """
    使用计数排序对颜色进行排序
    :param nums: List[int], 输入的整数数组,包含 0, 1, 2 代表不同颜色
    """
    count = {0: 0, 1: 0, 2: 0}
    for num in nums:
        count[num] += 1
    
    index = 0
    for color in range(3):
        for _ in range(count[color]):
            nums[index] = color
            index += 1
# 示例调用
nums = [2, 0, 2, 1, 1, 0]
sortColors(nums)
print(nums)  # 输出: [0, 0, 1, 1, 2, 2]
算法分析
  • 时间复杂度:(O(n)),其中 n 是数组的长度。
  • 空间复杂度:(O(1)),只使用了固定大小的额外空间。

方法二:一次遍历的荷兰国旗问题解法

解题步骤
  1. 初始化指针:设置三个指针,lowmidhigh 分别用于追踪 0 的右边界和 2 的左边界,以及当前考虑的元素。
  2. 迭代处理元素:移动mid指针,根据指向的值调整三个指针:
  • 如果 nums[mid] == 0,交换 nums[low]nums[mid],然后移动 lowmid 指针。
  • 如果 nums[mid] == 1,只移动 mid 指针。
  • 如果 nums[mid] == 2,交换 nums[mid]nums[high],然后移动 high 指针。
完整的规范代码
def sortColors(nums):
    """
    使用荷兰国旗问题的解法一次遍历解决颜色排序问题
    :param nums: List[int], 输入的整数数组,包含 0, 1, 2 代表不同颜色
    """
    low, mid, high = 0, 0, len(nums) - 1
    while mid <= high:
        if nums[mid] == 0:
            nums[low], nums[mid] = nums[mid], nums[low]
            low += 1
            mid += 1
        elif nums[mid] == 1:
            mid += 1
        else:
            nums[mid], nums[high] = nums[high], nums[mid]
            high -= 1
# 示例调用
nums = [2, 0, 1]
sortColors(nums)
print(nums)  # 输出: [0, 1, 2]
算法分析
  • 时间复杂度:(O(n)),只需要一次遍历。
  • 空间复杂度:(O(1)),不使用额外空间。

方法三:双指针优化

解题步骤
  1. 双指针初始化left 指向数组开头,right 指向数组结尾。
  2. 双指针移动:遍历数组,使用 leftright 两个指针分别处理 02,保持 1 自然位于中间。
完整的规范代码
def sortColors(nums):
    """
    使用双指针优化解决颜色分类问题
    :param nums: List[int], 输入的整数数组,包含 0, 1, 2 代表不同颜色
    """
    left, right = 0, len(nums) - 1
    i = 0
    while i <= right:
        if nums[i] == 0:
            nums[left], nums[i] = nums[i], nums[left]
            left += 1
            i += 1
        elif nums[i] == 2:
            nums[right], nums[i] = nums[i], nums[right]
            right -= 1
        else:
            i += 1
# 示例调用
nums = [2, 0, 2, 1, 1, 0]
sortColors(nums)
print(nums)  # 输出: [0, 0, 1, 1, 2, 2]
算法分析
  • 时间复杂度:(O(n)),在最坏的情况下,数组需要被遍历两次。
  • 空间复杂度:(O(1)),不需要额外空间。

方法四:简化的一次遍历

解题步骤
  1. 单次遍历:类似于荷兰国旗问题的解法,通过简化逻辑减少冗余操作。
  2. 直接交换:在遍历过程中,直接根据当前元素与 leftright 指针的关系进行交换。
完整的规范代码
def sortColors(nums):
    """
    使用简化的一次遍历方法对颜色进行分类
    :param nums: List[int], 输入的整数数组,包含 0, 1, 2 代表不同颜色
    """
    left, right = 0, len(nums) - 1
    i = 0
    while i <= right:
        while nums[i] == 2 and i < right:
            nums[i], nums[right] = nums[right], nums[i]
            right -= 1
        while nums[i] == 0 and i > left:
            nums[i], nums[left] = nums[left], nums[i]
            left += 1
        i += 1
# 示例调用
nums = [2, 0, 1]
sortColors(nums)
print(nums)  # 输出: [0, 1, 2]
算法分析
  • 时间复杂度:(O(n)),尽管存在嵌套循环,但每个元素最多被交换两次。
  • 空间复杂度:(O(1)),使用常数额外空间。

方法五:内置函数优化

解题步骤
  1. 计数:使用 Python 内置函数统计 012 的个数。
  2. 重构数组:根据统计结果重构原数组。
完整的规范代码
def sortColors(nums):
    """
    使用内置函数统计并重构数组
    :param nums: List[int], 输入的整数数组,包含 0, 1, 2 代表不同颜色
    """
    count = [0] * 3
    for num in nums:
        count[num] += 1
    
    index = 0
    for color in range(3):
        for _ in range(count[color]):
            nums[index] = color
            index += 1
# 示例调用
nums = [2, 0, 1]
sortColors(nums)
print(nums)  # 输出: [0, 1, 2]
算法分析
  • 时间复杂度:(O(n)),需要两次遍历数组,一次计数,一次重构。
  • 空间复杂度:(O(1)),使用了有限的额外空间。

不同算法的优劣势对比

特征 方法一:计数排序 方法二:荷兰国旗问题 方法三:双指针优化 方法四:简化一次遍历 方法五:内置函数优化
时间复杂度 (O(n)) (O(n)) (O(n)) (O(n)) (O(n))
空间复杂度 (O(1)) (O(1)) (O(1)) (O(1)) (O(1))
优势 易于实现 单次遍历 降低遍历次数 高效处理 简洁,利用内置优化
劣势 两次遍历 需要掌握指针逻辑 较复杂的指针移动 潜在的多次交换 依赖于语言特性

应用示例

数据科学:在数据预处理阶段,快速分类和标记数据是常见需求,这些方法可以快速实现。

软件开发:在用户界面开发中,可能需要对大量颜色标签进行排序,以便更快地访问和渲染。

算法竞赛:在算法竞赛中,这些方法可以用来快速解决与分类和排序相关的问题,是提高效率的关键。欢迎关注微信公众号 数据分析螺丝钉

相关文章
|
11天前
|
机器学习/深度学习 计算机视觉 异构计算
基于YOLOv8深度学习的玉米叶片病害智能诊断与防治系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分类(2)
基于YOLOv8深度学习的玉米叶片病害智能诊断与防治系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分类
基于YOLOv8深度学习的玉米叶片病害智能诊断与防治系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分类(2)
|
15天前
|
SQL 算法 数据可视化
LeetCode题目92:反转链表ll 【python 递归与迭代方法全解析】
LeetCode题目92:反转链表ll 【python 递归与迭代方法全解析】
|
8天前
|
开发工具 Python
[oeasy]python0021_宝剑镶宝石_爱之石中剑_批量替换_特殊字符_特殊颜色
在这个文本中,作者描述了一个逐步修改Python游戏`game.py`的过程,以将小丑的眼睛和石中剑的图形替换为爱心符号,并且将其颜色更改为红色。以下是内容的摘要: - 用户回顾了之前对`game.py`的分析和理解。 - 通过使用方向键和编辑模式,在代码中找到了小丑眼睛和石中剑的位置,用爱心符号(❤)替换了它们。 - 如果遇到问题,建议使用最新版的火狐浏览器进行粘贴操作。 - 使用Vim编辑器的命令模式批量替换了剑柄上的数字8为爱心,使整个剑柄充满了爱心。 - 通过插入特定代码,将爱心变为红色,从而得到红色的“爱之大剑”。
11 0
|
11天前
|
机器学习/深度学习 计算机视觉 异构计算
基于YOLOv8深度学习的橙子病害智能诊断与防治系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分类(2)
基于YOLOv8深度学习的橙子病害智能诊断与防治系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分类
|
11天前
|
机器学习/深度学习 监控 Python
基于YOLOv8深度学习的橙子病害智能诊断与防治系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分类(1)
基于YOLOv8深度学习的橙子病害智能诊断与防治系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分类
|
11天前
|
机器学习/深度学习 监控 搜索推荐
基于YOLOv8深度学习的玉米叶片病害智能诊断与防治系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分类(1)
基于YOLOv8深度学习的玉米叶片病害智能诊断与防治系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标分类
|
15天前
|
SQL 算法 数据可视化
LeetCode题目99:图解中叙遍历、Morris遍历实现恢复二叉树搜索树【python】
LeetCode题目99:图解中叙遍历、Morris遍历实现恢复二叉树搜索树【python】
|
10天前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-2
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
10天前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-1
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
11天前
|
索引
【LeetCode刷题】二分查找:山脉数组的峰顶索引、寻找峰值
【LeetCode刷题】二分查找:山脉数组的峰顶索引、寻找峰值