郭峰博客 郭峰博客
首页
LeetCode
  • Algorithm
GitHub (opens new window)

挥码天涯

以梦为马,挥码天涯
首页
LeetCode
  • Algorithm
GitHub (opens new window)
  • 1.【简单】两数之和
  • 7.【简单】整数反转
  • 9.【简单】回文数
  • 11.【中等】回文数
  • 13.【简单】罗马数字转整数
  • 14.【简单】最长公共前缀
  • 15.【中等】三数之和
  • 19.【中等】删除链表的倒数第N个节点
  • 20.【简单】有效的括号
  • 21.【简单】合并两个有序链表
  • 26.【简单】排除数组中的重复项
  • 27.【简单】移除元素
  • 28.【简单】实现strStr
  • 35.【简单】搜索插入位置
  • 51. 【困难】数组中的逆序对.md
  • 58.【简单】最后一个单词的长度
  • 57.【中等】颜色分类
    • 题目来源:
    • 题目
    • 分析
    • 代码
  • 100.【简单】相同的树
  • 168.【简单】缺失数字
  • 175.【简单】组合两表
  • 176.【简单】第二高的薪水.md
  • 176.【中等】第二高的薪水.md
  • 206.【简单】反转链表
  • 215.【中等】数组中的第K个最大元素
  • 875.【中等】爱吃香蕉的珂珂
  • LeetCode
feng.guo
2021-09-22
目录

57.【中等】颜色分类

文章发布较早,内容可能过时,阅读注意甄别。

# 题目来源:

题目来源

# 题目

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

此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

示例 1:

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

示例 2:

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

示例 3:

输入:nums = [0]
输出:[0]
1
2

示例 4:

输入:nums = [1]
输出:[1]
1
2

# 分析

使用三路快速排序法能快速解决
,这个问题是非常典型的,可以使用三路快速排序的 partition 思想解决的问题。因为,整个数组中只有 0, 1, 2 三种元素。如果我们把 1 当做标定点的话,就自然而然的可以把元素 0 当做是小于标定点的部分,元素 2 当做是大于标定点的部分。 所以,大家可以看出来,只要我们使用 1 当做标定点,只需要运行一遍三路快速排序的 partition 过程,就能完成任务了:) 注意,在这个过程中,我们不需要随机去选择标定点了,我们已经通过对问题的分析,明确了标定点就是 1。同时,我们也不需要一定把一个 1 放在整个数组的最左边。既然我们明确了标定点是 1,在算法循环过程中,每个待处理的元素,直接和 1 进行比较就好了。 在下面的代码中,循环不变量的定义是:

nums[0...zero] == 0
nums[zero + 1, i - 1] == 1
nums[two, n - 1] == 2
1
2
3

其实,变量 zero 相当于我们在三路快速排序算法中的 lt; 变量 two 相当于我们在三路快速排序算法中的 gt。 有了这个定义,相信理解了快速排序算法的 partition 的逻辑,可以很容易地写出正确的代码。

# 代码

class Solution {

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

   private void swap(int[] nums, int i, int j){
       int t = nums[i];
       nums[i]= nums[j];
       nums[j] = t;
   }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
执行用时:0 ms, 在所有 Java 提交中击败了100.00%
1
微信 支付宝
#排序
上次更新: 2024/03/07, 20:33:54

← 58.【简单】最后一个单词的长度 100.【简单】相同的树→

最近更新
01
2.实现一个Stack
10-30
02
01.实现一个链表结构
10-30
03
博客导引
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2024
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式