news 2026/5/25 5:46:58

LeetCode 75:颜色分类 | 荷兰国旗问题的多种解法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 75:颜色分类 | 荷兰国旗问题的多种解法

LeetCode 75:颜色分类 | 荷兰国旗问题的多种解法

引言

颜色分类(Sort Colors)是 LeetCode 第 75 题,难度为 Medium。题目要求将包含 0、1、2 三种值的数组排序,使所有 0 在前面,所有 1 在中间,所有 2 在后面。这道题也被称为荷兰国旗问题,是三路分区的经典案例。

这道题有多种解法:计数排序 O(n) 两趟、原地交换 O(n) 一趟。本文将详细介绍这两种解法及其优化。

问题分析

题目描述

给定一个数组 nums,元素只有 0、1、2 三种值,原地排序使数组变为有序。例如,输入 [2,0,2,1,1,0],输出 [0,0,1,1,2,2]。

问题特点

这道题的核心挑战在于如何在一趟遍历中完成排序。传统的排序算法(如快速排序)可以解决这个问题,但需要 O(n log n) 时间。荷兰国旗问题要求 O(n) 时间和 O(1) 空间。

解法一:计数排序

算法原理

计数排序是一种简单的解法。首先统计 0、1、2 的数量,然后重写数组。

def sortColors_counting(nums): count = [0, 0, 0] for num in nums: count[num] += 1 index = 0 for i in range(3): for _ in range(count[i]): nums[index] = i index += 1

复杂度分析

时间复杂度:O(n),两趟遍历
空间复杂度:O(1)

解法二:三路分区(单趟)

算法原理

使用三个指针:zero 指向 0 区的右边界,two 指向 2 区的左边界,cur 指向当前遍历位置。

def sortColors_three_way(nums): zero = 0 two = len(nums) - 1 cur = 0 while cur <= two: if nums[cur] == 0: nums[zero], nums[cur] = nums[cur], nums[zero] zero += 1 cur += 1 elif nums[cur] == 2: nums[two], nums[cur] = nums[cur], nums[two] two -= 1 else: cur += 1

算法详解

初始状态:zero = 0,two = n-1,cur = 0

  • 0 区:索引 [0, zero)
  • 未排序区:[cur, two]
  • 2 区:(two, n-1]

当 nums[cur] == 0 时,与 zero 位置交换,zero 和 cur 都右移。
当 nums[cur] == 2 时,与 two 位置交换,two 左移(cur 不变,因为交换过来的元素还没检查)。
当 nums[cur] == 1 时,cur 右移。

复杂度分析

时间复杂度

时间复杂度为 O(n),因为 cur 最多移动 n 次,zero 和 two 也最多移动 n 次。

空间复杂度

空间复杂度为 O(1),只使用了三个指针变量。

代码实现

Python 实现

def sortColors(nums): zero = 0 two = len(nums) - 1 cur = 0 while cur <= two: if nums[cur] == 0: nums[zero], nums[cur] = nums[cur], nums[zero] zero += 1 cur += 1 elif nums[cur] == 2: nums[two], nums[cur] = nums[cur], nums[two] two -= 1 else: cur += 1

Java 实现

public void sortColors(int[] nums) { int zero = 0; int two = nums.length - 1; int cur = 0; while (cur <= two) { if (nums[cur] == 0) { swap(nums, zero, cur); zero++; cur++; } else if (nums[cur] == 2) { swap(nums, two, cur); two--; } else { cur++; } } } private void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; }

边界情况处理

空数组

当数组为空时,循环不会执行,直接返回。

全相同元素

当所有元素都相同时,如 [1, 1, 1],算法会正确处理:cur 会一直右移到 two 位置,然后结束。

测试用例

def test_sort_colors(): nums1 = [2, 0, 2, 1, 1, 0] sortColors(nums1) assert nums1 == [0, 0, 1, 1, 2, 2] nums2 = [2, 0, 1] sortColors(nums2) assert nums2 == [0, 1, 2] nums3 = [0] sortColors(nums3) assert nums3 == [0] nums4 = [1, 1, 1] sortColors(nums4) assert nums4 == [1, 1, 1] print("所有测试用例通过!")

总结

颜色分类问题展示了荷兰国旗问题的标准解法。三路分区方法只需要一趟遍历就将数组排序,时间复杂度 O(n),空间复杂度 O(1),是解决这类问题的最优方法。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/25 5:46:38

AI流体预测:精度、效率与碳足迹的权衡与流匹配实践

1. 项目概述与核心问题 在流体动力学、气候模拟乃至材料科学等领域&#xff0c;预测物理场的时空演化一直是个计算密集型任务。传统的高保真数值模拟&#xff0c;比如求解完整的Navier-Stokes方程&#xff0c;虽然精度高&#xff0c;但计算成本极其昂贵&#xff0c;一次模拟可能…

作者头像 李华
网站建设 2026/5/25 5:42:03

Unity入门:从创建立方体理解组件化三维工作流

1. 这不是“Hello World”&#xff0c;而是你和Unity第一次真正握手很多人点开Unity安装包那一刻&#xff0c;以为接下来就是拖拽、点击、三分钟出效果——结果新建项目后面对空荡荡的Scene视图和一堆灰色面板&#xff0c;连“立方体在哪”都找不到。我带过三十多期Unity新手训…

作者头像 李华
网站建设 2026/5/25 5:41:06

SkyWalking SQL注入漏洞深度解析与实战加固指南

1. 这不是一次“普通”的SQL注入&#xff1a;为什么SkyWalking的CVE-2020-9483和CVE-2020-13921值得所有后端与可观测性工程师反复咀嚼Apache SkyWalking 是国内中大型技术团队在微服务可观测性领域事实上的首选方案——它不依赖Java Agent侵入式改造&#xff0c;支持多语言探针…

作者头像 李华
网站建设 2026/5/25 5:35:03

图自编码器在金融风控中的拓扑模式识别实践

1. 项目概述&#xff1a;为什么金融风控需要“看图说话”&#xff1f;干了这么多年金融科技和数据安全&#xff0c;我越来越觉得&#xff0c;传统的风控系统就像是在用渔网捞鱼——网眼大小固定&#xff0c;只能抓住那些体型符合预期的“鱼”。一旦犯罪分子学会了“变形”&…

作者头像 李华
网站建设 2026/5/25 5:30:13

如何集成OpenClaw?2026年腾讯云部署及配置Token Plan保姆级步骤

如何集成OpenClaw&#xff1f;2026年腾讯云部署及配置Token Plan保姆级步骤。OpenClaw是开源的个人AI助手&#xff0c;Hermes Agent则是一个能自我进化的AI智能体框架。阿里云提供计算巢、轻量服务器及无影云电脑三种部署OpenClaw 与 Hermes Agent的方案、百炼Token Plan兼容主…

作者头像 李华
网站建设 2026/5/25 5:30:10

智慧三层停车场系统

&#x1f17f;️ 智慧停车场系统简介 本系统是一套集数据监控、智能调度、订单管理与车位资源优化于一体的现代化停车场管理平台。通过大屏可视化方式&#xff0c;实时展示停车场运营状态&#xff0c;适用于大型商业综合体、园区、交通枢纽等场景。 &#x1f4ca; 核心数据监…

作者头像 李华