LeetCode   分类颜色

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

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

注意:
不能使用代码库中的排序函数来解决这道题。

示例:

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

进阶:

    • 一个直观的解决方案是使用计数排序的两趟扫描算法。
      首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。
    • 你能想出一个仅使用常数空间的一趟扫描算法吗?

1.   使用基数排序:

 class Solution:
def sortColors(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
#桶排序
count = []
for i in [0,1,2]:
count.append(nums.count(i))
j=0
for i in [0,1,2]:
while count[i]>0:
nums[j] = i
j += 1
count[i] -= 1
print(nums)

2.    使用快排:

两路快排的Partition的实现(c++):

 // v为pivot,初始存储在arr[l]的位置
int j = l; // 循环过程保持 arr[l+1...j] < v ; arr[j+1...i) > v
for( int i = l + 1 ; i <= r ; i ++ )
if( arr[i] < v )
swap( arr[++j] , arr[i] );
swap( arr[l] , arr[j]); // 此时,j指向pivot的正确位置
 class Solution:
def _sortColors(self, nums, l, r):
if l >= r:
return
# pratition
j = l+1
pivot = nums[l]
for i in range(l+1, r+1):
if nums[i] < pivot:
nums[i], nums[j] = nums[j], nums[i]
j += 1
j -= 1
nums[l], nums[j] = nums[j], nums[l] #devide
self._sortColors(nums, l, j-1)
self._sortColors(nums, j+1, r)
def sortColors(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
self._sortColors(nums, 0, len(nums)-1)

这样的一个快排,在面临有序或者近乎有序的数组时,会退化成为一个O(n^2)的算法。于是我们使用了一个很简单的随机选取pivot的方式来处理这个问题。这步随机化让快速排序的时间期望成为了O(nlogn),并且只有极低的概率退化为O(n^2)。
    面对有大量重复元素的数据时,还是有可能退化成O(n^2)级别的。通过这个思路,我们可以进一步优化,提出三路快排的思想。

3.   三路快排

三路快排的Partition代码是这样的。

 // v为pivot,初始存储在arr[l]的位置
int lt = l; // 循环过程中保持 arr[l+1...lt] < v
int gt = r + ; // 循环过程中保持 arr[gt...r] > v
int i = l+; // 循环过程中保持 arr[lt+1...i) == v
while( i < gt ){
if( arr[i] < v ){
swap( arr[i++], arr[lt+]); lt ++; }
else if( arr[i] > v ){
swap( arr[i], arr[gt-]); gt --; }
else // arr[i] == v
i ++;
}
swap( arr[l] , arr[lt] );
// 此时 arr[lt...gt-1]部分为数组中元素等于v的部分
// 之后只需要递归地对arr[l...lt-1]和arr[gt...r]两部分进行三路快排即可
 class Solution:
def _sortColors(self, nums, l, r):
if l >= r:
return
# pratition
pivot = nums[l]
j = l+1 #循环过程中保持 arr[lt+1...j) == v
lt = l #循环过程中保持 arr[l+1...lt] < v
gt = r # 循环过程中保持 arr[gt...r] > v
while j <= gt:
if nums[j] < pivot:
nums[lt], nums[j] = nums[j], nums[lt]
j += 1
lt += 1
elif nums[j] > pivot:
nums[gt], nums[j] = nums[j], nums[gt]
gt -= 1
else:
j += 1 #devide
self._sortColors(nums, l, lt-1)
self._sortColors(nums, gt+1, r)
def sortColors(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
self._sortColors(nums, 0, len(nums)-1)

LeetCode 分类颜色的更多相关文章

  1. LeetCode:颜色分类【75】

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

  2. [leetcode] 75. 分类颜色(常数空间且只扫描一次算法)

    75. 分类颜色 我们直接按难度最高的要求做:你能想出一个仅使用常数空间的一趟扫描算法吗? 常数空间 只能扫描一趟.注意,是一趟,而不是O(n) 题中只会出现3个数字:0,1,2.换句话说,0肯定在最 ...

  3. LeetCode 75. 颜色分类(Sort Colors) 30

    75. 颜色分类 75. Sort Colors 题目描述 给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中, ...

  4. Leetcode 75.颜色分类 By Python

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

  5. leetcode 75颜色分类

    两趟扫描,由于排序变量的特殊性,使用计数排序方法可以明显降低至O(n)time O(n) space 关于计数排序:https://mp.weixin.qq.com/s/WGqndkwLlzyVOHO ...

  6. Java实现 LeetCode 75 颜色分类

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

  7. LeetCode(75):分类颜色

    Medium! 题目描述: 给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中,我们使用整数 0. 1 和 2 ...

  8. leetcode 75. 颜色分类 JAVA

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

  9. Leetcode 75. 颜色分类

    题目链接 https://leetcode-cn.com/problems/sort-colors/description/ 题目描述 给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们 ...

随机推荐

  1. Java高并发程序设计学习笔记(十):并发调试和JDK8新特性

    转自:https://blog.csdn.net/dataiyangu/article/details/87631574 多线程调试的方法使用Eclipse进行多线程调试线程dump及分析分析死锁案例 ...

  2. mybatis报错,There is no getter for property named 'templateName' in 'class

    There is no getter for property named 'templateName' in 'class 主要原因是因为mapper.xml 的语句有错误,导致在bean里找不到相 ...

  3. C++虚函数和纯虚函数的用法和区别

    C++虚函数与纯虚函数用法与区别(转)   1. 虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能 ...

  4. loadrunner执行场景时报Error -27040: Data Format Extension: Init: Internal error问题解决

    [问题描述] 在loadrunner控制台执行场景时,所有用户均Failed,查看errors,错误原因如下: Error -27040: Data Format Extension: Init: I ...

  5. Oracle笔记(二) SQLPlus命令

    对于Oracle数据库操作主要使用的是命令行方式,而所有的命令都使用sqlplus完成,对于sqlplus有两种形式. 一种是dos风格的sqlplus:sqlplus.exe; 另一种是window ...

  6. Docker容器入门篇

    第1章 Docker简介 1.1 Docker容器介绍 Docker官网:https://www.docker.com/ 什么是docker? Docker 最初是 dotCloud 公司创始人 So ...

  7. Task扩展方法取消操作

    /// <summary> /// 任务扩展,传入取消操作 /// </summary> public static class TaskExtensionDemo { //因 ...

  8. libusb_transfer

    http://libusb.sourceforge.net/api-1.0/structlibusb__transfer.html int libusb_control_transfer(libusb ...

  9. sscanf功能详解(转)

    在处理字符串的程序当中,经常会分析字符串,从一大长串的字符串截取我们需要的数据,这如果通过自己手写函数来分析,虽然可以,但当你知道sscanf的功能,那就自己写函数分析就显得多此一举. 这些函数的使用 ...

  10. 解决使用vue打包时vendor文件过大或者是app.js文件很大的问题

    这篇文章主要介绍了使用vue打包时vendor文件过大或者是app.js文件很大问题的解决方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下 第一次使用vue2.0开发,之前都是用的angu ...