文章目录

  • 1 题目
  • 2 解决方案
    • 2.1 思路
    • 2.2 图解
    • 2.3 时间复杂度
    • 2.4 空间复杂度
  • 3 源码

1 题目

题目:颜色分类II(Sort Colors II)
描述:给定一个有n个对象(包括k种不同的颜色,并按照1到k进行编号)的数组,将对象进行分类使相同颜色的对象相邻,并按照1,2,…k的顺序进行排序。

  1. 不能使用代码库中的排序函数来解决这个问题
  2. k <= n

lintcode题号——143,难度——medium

样例1:

输入:
[3,2,2,1,4]
4
输出: [1,2,2,3,4]

样例2:

输入:
[2,1,1,2,2]
2
输出: [1,1,2,2,2]

2 解决方案

2.1 思路

  将两组元素进行排序需要用双指针,将三组元素进行排序需要用三指针,该题需要排序的颜色种类不确定,无法直接套用相应的指针算法,一种笨办法是先排序出[颜色1,(颜色2,颜色3,...)],再排序出[颜色1,颜色2,(颜色3,...)],这样可以把该题当成每次都对两组元素进行排序的情况来做,时间复杂度O(n^k)。
  考虑进行优化,该题可以用一种更优的算法解决,参考快速排序的思想,将颜色进行分治,而不是一个个颜色去排,将区间按照颜色向下细分,每次用O(n)的耗时将规模为T(k)的问题变为2*T(k/2)的规模,将时间复杂度降为O(n * log k)。

其实该题可以直接通过快速排序解决,不过时间复杂度为O(n * log n)。彩虹排序可以看作对快速排序在特定情况下的优化,将时间复杂度降为O(n * log k),其中n为数组元素个数,k为颜色种类数量。

2.2 图解

假设颜色顺序为(赤,橙,黄,绿,青,蓝,紫):

#mermaid-svg-2gDGKRncIzRbxPDv {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-2gDGKRncIzRbxPDv .error-icon{fill:#552222;}#mermaid-svg-2gDGKRncIzRbxPDv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2gDGKRncIzRbxPDv .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-2gDGKRncIzRbxPDv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2gDGKRncIzRbxPDv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2gDGKRncIzRbxPDv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2gDGKRncIzRbxPDv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2gDGKRncIzRbxPDv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2gDGKRncIzRbxPDv .marker.cross{stroke:#333333;}#mermaid-svg-2gDGKRncIzRbxPDv svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2gDGKRncIzRbxPDv .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-2gDGKRncIzRbxPDv .cluster-label text{fill:#333;}#mermaid-svg-2gDGKRncIzRbxPDv .cluster-label span{color:#333;}#mermaid-svg-2gDGKRncIzRbxPDv .label text,#mermaid-svg-2gDGKRncIzRbxPDv span{fill:#333;color:#333;}#mermaid-svg-2gDGKRncIzRbxPDv .node rect,#mermaid-svg-2gDGKRncIzRbxPDv .node circle,#mermaid-svg-2gDGKRncIzRbxPDv .node ellipse,#mermaid-svg-2gDGKRncIzRbxPDv .node polygon,#mermaid-svg-2gDGKRncIzRbxPDv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2gDGKRncIzRbxPDv .node .label{text-align:center;}#mermaid-svg-2gDGKRncIzRbxPDv .node.clickable{cursor:pointer;}#mermaid-svg-2gDGKRncIzRbxPDv .arrowheadPath{fill:#333333;}#mermaid-svg-2gDGKRncIzRbxPDv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2gDGKRncIzRbxPDv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2gDGKRncIzRbxPDv .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-2gDGKRncIzRbxPDv .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-2gDGKRncIzRbxPDv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2gDGKRncIzRbxPDv .cluster text{fill:#333;}#mermaid-svg-2gDGKRncIzRbxPDv .cluster span{color:#333;}#mermaid-svg-2gDGKRncIzRbxPDv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2gDGKRncIzRbxPDv :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

小于等于绿色的
大于绿色的
小于等于橙色的
大于橙色的
小于等于蓝色的
大于蓝色的
小于等于赤色的
大于赤色的
小于等于黄色的
大于黄色的
小于等于青色的
大于青色的
赤,黄,青,蓝,绿,蓝,橙,黄,黄,紫,赤,紫
赤,黄,橙,黄,黄,绿,赤
青,蓝,紫,蓝,紫
赤,橙,赤
黄,黄,黄,绿
青,蓝,蓝
紫,紫
赤,赤
黄,黄,黄
绿
蓝,蓝
紫,紫
赤,赤,橙,黄,黄,黄,绿,青,蓝,蓝,紫,紫

2.3 时间复杂度

  每次使用O(n)的耗时将规模为T(k)的问题变为2*T(k/2)的规模,时间复杂度的计算如下:

T(k) = 2 * T(k/2) + O(n)............................(n=k)= 2 * (2*T(k/4) + O(k/2)) + O(n).............(n=k/2)= 4 * T(k/4) + 2*O(k/2) + O(n)= 4 * (2*T(k/8) + O(k/4)) + 2*O(k/2) + O(n)..(n=k/4)= 8 * T(k/8) + 4*O(k/4) + 2*O(k/2) + O(n)= k * T(k/k) + O(k) + O(k) + …… + O(n)= k*T(1) + (logk - 1)*O(k) + O(n)= O(k) + (logk - 1)*O(k) + O(n)= O(nlogk) + O(n)= O(nlogk)

  所以总的时间复杂度为O(n * log k)。

2.4 空间复杂度

  空间复杂度为O(1)。

3 源码

细节:

  1. 彩虹排序算法,递归的定义需要包含索引的起止位置(start,end)以及颜色的起止位置(colorStart,colorEnd)。
  2. 将区间按照颜色向下细分,每次用O(n)的耗时将规模为T(k)的问题变为2*T(k/2)的规模,时间复杂度O(n * log k)。(n为数组长度,k为颜色种类)
  3. 索引范围的操作类似快速排序的left和right。
  4. 排序范围的操作类似合并排序的区间(left,mid)和(mid+1,right)。

C++版本:

/**
* @param colors: A list of integer
* @param k: An integer
* @return: nothing
*/
void sortColors2(vector<int> &colors, int k) {// write your code hereif (colors.empty()){return;}rainbowSort(colors, 0, colors.size() - 1, 1, k);
}// 对数组中从start到end的位置进行排序,排序区间内的颜色分布从colorStart到colorEnd
void rainbowSort(vector<int> & colors, int start, int end, int colorStart, int colorEnd)
{if (colorStart == colorEnd) // 只有一种颜色,不需要继续排序{return;}if (start == end) // 只有一个元素,不需要继续排序{return;}int left = start;int right = end;int colorMid = colorStart + (colorEnd - colorStart) / 2;while (left <= right){if (colors.at(left) <= colorMid) // 按照颜色划分左右区间{left++;continue;}if (colors.at(right) > colorMid) // 按照颜色划分左右区间{right--;continue;}swap(colors.at(left++), colors.at(right--));}rainbowSort(colors, start, right, colorStart, colorMid);rainbowSort(colors, left, end, colorMid + 1, colorEnd);
}

82 颜色分类II-彩虹排序(Sort Colors II)相关推荐

  1. 143. Sort Colors II - 排颜色 II(rainbowSort彩虹排序)

    Description 给定一个有n个对象(包括k种不同的颜色,并按照1到k进行编号)的数组,将对象进行分类使相同颜色的对象相邻,并按照1,2,...k的顺序进行排序. 注意事项 You are no ...

  2. leetcode系列-颜色分类(sort colors)

    分类:array 难度:medium 颜色分类 给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中,我们使用整数 ...

  3. LeetCode--75.颜色分类(三路快排,计数排序)

    颜色分类(C) 1. 题目描述 2. 题目解析 3. C语言实现 3.1 三路快排法 3.2 计数排序法 1. 题目描述 难度:中等 2. 题目解析 这道题需要注意一下几点: 原地进行排序,不可以另外 ...

  4. 【排序】LeetCode 75. Sort Colors

    LeetCode 75. Sort Colors Solution1: 参考自:<leetcode-cpp 答案> 由于0,1,2非常紧凑,首先想到计数排序(counting sort), ...

  5. (转!)利用Keras实现图像分类与颜色分类

    2018-07-19 全部谷歌渣翻加略微修改 大家将就的看哈 建议大佬们还是看看原文 点击收获原文 其中用到的示例文件 multi-output-classification 大家可以点击 下载 . ...

  6. 《LeetCode力扣练习》第75题 颜色分类 Java

    <LeetCode力扣练习>第75题 颜色分类 Java 一.资源 题目: 给定一个包含红色.白色和蓝色.共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按 ...

  7. leetcode必刷题(四)lee75 颜色分类、lee76 最小覆盖字串、lee78 子集、lee79 单词搜索、lee84 柱状图中最大的矩形、lee85 最大矩形、lee96 不同的二叉搜索树、

    lee75 颜色分类 patition 三个指针 lee76 最小覆盖字串 滑动窗口 lee78 子集 无重复数字 回溯 lee79 单词搜索 回溯 lee84 柱状图中最大的矩形 单调栈 lee85 ...

  8. 【leetcode】75.颜色分类(多种解法,超详细图文解析)

    75. 颜色分类 难度中等 给定一个包含红色.白色和蓝色,一共 n 个元素的数组,**原地**对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中,我们使用整数 0. 1 ...

  9. LeetCode - 75 颜色分类

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

最新文章

  1. 数据预处理常用技巧 | 数据分析中如何处理缺失值?(文末福利)
  2. 拼多多出现大Bug:100无门槛券随便领,一晚损失200亿
  3. “我哥毕业1年,做Python挣了50W!”网友:吹得太少...
  4. 动态网页开发技术(三):jsp
  5. (1)ActivityThread分析
  6. ios 高德地图加载瓦片地图_iOS 利用高德地图WMS服务
  7. android 半透明色值_最全的Android 颜色透明度
  8. 福昕阅读器 自定义注释快捷键
  9. 对称密钥加密和非对称密钥加密
  10. 基于.net开发chrome核心浏览器【三】
  11. 软件测试的目的、原则及流程
  12. 鼠标悬停图标360度旋转效果
  13. Linux下安装Adobe Flash Player插件(Firefox)
  14. java.lang.ClassNotFoundException解决办法
  15. 炮兵阵地(状压dp)
  16. linux中常见中英文单词对照表
  17. 大多数企业数字化转型的真正目的其实只是为了能多裁点人
  18. day06_类与对象
  19. 【冰爪游戏】MC教程 —— PCL启动器
  20. 张驰课堂:2022年CAQ中质协六西格玛考试时间通知

热门文章

  1. MES管理系统如何帮助企业建设透明化智慧工厂
  2. Unity 动态循环设置材质球的图片
  3. Netty4.x用POJO代替ByteBuf案例
  4. 技术股份5%是个什么概念?
  5. 当我们投稿被要求补充实验,怎么办?
  6. python小乌龟代码_python小乌龟
  7. Button字体大写
  8. 新视野大学英语(第三版)第一册课后习题答案(完整版)
  9. 保护气体在焊接中的作用和特征
  10. 今天,你“刷脸开门”了吗?