描述
给定一个有n个对象(包括k种不同的颜色,并按照1到k进行编号)的数组,将对象进行分类使相同颜色的对象相邻,并按照1,2,...k的顺序进行排序
- 不能使用代码库中的排序函数来解决这个问题
k<=n
样例1
输入:
[3,2,2,1,4]
4
输出:
[1,2,2,3,4]
样例2
输入:
[2,1,1,2,2]
2
输出:
[1,1,2,2,2]
挑战
可直接使用计数排序算法扫描两遍,但这样会花费O(k)的额外空间。你能否在O(logk)的额外空间的情况下完成
思路:首先第一种最简单的方法是快速排序 第二种是快速排序的改进版 增加了颜色的数量
代码如下:
第一种:
public class Solution {
/**
* @param colors: A list of integer
* @param k: An integer
* @return: nothing
*/
public void sortColors2(int[] colors, int k) {//一定有重复的元素 考察排序算法特别是交换算法 常用的有冒泡和快速排序
// write your code here
//快速排序
quickSort(colors,0,colors.length-1);
}
public void quickSort(int[] a,int start,int end)
{
if (start >= end)
{
return;
}
int pivot=a[start+(end-start)/2];//枢轴值 枢轴值作为每轮目标值 进行排序
int left=start, right=end;
while(left<=right)
{
while(a[left]<pivot)//注意是while 而不是if pivot = 数组里的某个元素 → 用 小于 或者大于 就够了 不能写<=或者>= 写了之后就会跳过去,不会停下,造成分区错误
{
left++;
}
while(a[right]>pivot)
{
right--;
}
if (left <= right)
{
swapElement(a, left, right);
left++; right--;
}
}
quickSort(a,start,right);
quickSort(a,left,end);
}
public void swapElement(int a[],int left,int right)
{
int temp=a[left];
a[left]=a[right];
a[right]=temp;
}
}
第二种:前面的一种pivot是数组中间的一个元素值
而这一种是通过颜色进行分割的
有了颜色区间,就能稳定地把元素按 ≤ColorMid和 >ColorMid来分,保证颜色范围被均匀拆开
代码如下:
public class Solution {
/**
* @param colors: A list of integer
* @param k: An integer
* @return: nothing
*/
public void sortColors2(int[] colors, int k) {//一定有重复的元素 考察排序算法特别是交换算法 常用的有冒泡和快速排序
// write your code here
//快速排序
quickSort(colors,0,colors.length-1,1,k);//注意这里的颜色区间为1...k 而不是0...k
}
public void quickSort(int[] a,int start,int end,int colorStart,int colorEnd)
{
if (start >= end|| colorStart == colorEnd)
{
return;
}
int left=start, right=end;
int ColorMid=colorStart+(colorEnd-colorStart)/2;
while(left<=right)
{
while(left<=right&&a[left]<=ColorMid)//注意是while 而不是if pivot = 颜色区间的中点 → 必须明确规定“等于中点”的颜色归到哪边,所以用 <= 和 >
{
left++;
}
while(left<=right&&a[right]>ColorMid)
{
right--;
}
if (left <= right)
{
swapElement(a, left, right);
left++; right--;
}
}
quickSort(a,start,right,colorStart,ColorMid);
quickSort(a,left,end,ColorMid+1,colorEnd);// 改:ColorMid+1 按数组值的枢轴”换成了“按颜色区间中点划分
}
public void swapElement(int a[],int left,int right)
{
int temp=a[left];
a[left]=a[right];
a[right]=temp;
}
}

9309

被折叠的 条评论
为什么被折叠?



