描述
给定一个有n个对象(包括k种不同的颜色,并按照1到k进行编号)的数组,将对象进行分类使相同颜色的对象相邻,并按照1,2,...k的顺序进行排序。
You are not suppose to use the library's sort function for this problem.
k <= n
您在真实的面试中是否遇到过这个题?
是
样例
给出colors=[3, 2, 2, 1, 4]
,k=4
, 你的代码应该在原地操作使得数组变成[1, 2, 2, 3, 4]
挑战
一个相当直接的解决方案是使用计数排序扫描2遍的算法。这样你会花费O(k)的额外空间。你否能在不使用额外空间的情况下完成?
这一题是上一题的升级版,上一题见:https://blog.csdn.net/wenqiwenqi123/article/details/80819338
确保你明白上一题的思路和解法,再往下看。
当然这一题如果用挑战里说的那个方法就很简单了,问题是如何不使用额外空间。
这里给大家介绍一种排序,彩虹排序。时间复杂度为O(nlogk),n为数组长度,k为有多少种不同数字。
那么为什么时间复杂度会是这样呢,很简单,每一次遍历数组,也就是每一次花费O(n)的时间后,将问题规模降到k/2。
这个思想有点像归并排序,但实现的时候有点像快排。具体看代码里的注释:
class Solution:
"""
@param colors: A list of integer
@param k: An integer
@return: nothing
"""
def sortColors2(self, colors, k):
# write your code here
#colorFrom和colorTo是此时k的范围
#left和right是数组范围
def rainbowSort(colors,left,right,colorFrom,colorTo):
if(colorFrom==colorTo):
return
if(left>=right):
return
#每次递归的时候取mid,将k规模的问题分为k//2
colorMid=(colorFrom+colorTo)//2
l,r=left,right
while(l<=r):
while(l<=r and colors[l]<=colorMid):
l+=1
while(l<=r and colors[r]>colorMid):
r-=1
if(l<=r):
temp=colors[l]
colors[l]=colors[r]
colors[r]=temp
l+=1
r-=1
rainbowSort(colors,left,r,colorFrom,colorMid)
rainbowSort(colors,l,right,colorMid+1,colorTo)
if(colors==None or len(colors)==0):
return colors
rainbowSort(colors,0,len(colors)-1,1,k)
return colors
s = Solution()
print(s.sortColors2([4,5,3,2,1],5))