给定一个有n个对象(包括k种不同的颜色,并按照1到k进行编号)的数组,将对象进行分类使相同颜色的对象相邻,并按照1,2,...k的顺序进行排序。
样例
给出colors=[3, 2, 2, 1, 4]
,k=4
, 你的代码应该在原地操作使得数组变成[1, 2, 2, 3, 4]
挑战
一个相当直接的解决方案是使用计数排序扫描2遍的算法。这样你会花费O(k)的额外空间。你否能在不使用额外空间的情况下完成?
解题思路1:
就如上所说使用计数排序,题目类似于Lintcode 148. 颜色分类。
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
int[] nums = new int[k+1];
for(int i : colors)
nums[i]++;
int index = 0;
for(int i=1; i<=k; i++){
while(nums[i] > 0){
colors[index++] = i;
nums[i]--;
}
}
}
}
解题思路2:
手写双路快排
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);
}
private void quickSort(int[] colors, int l,int r){
if(l >= r)
return;
int p = partition(colors, l, r);
quickSort(colors, l, p-1);
quickSort(colors, p+1, r);
}
private int partition(int[] colors, int l, int r){
int randomIndex = l + (int)(Math.random()*(r-l+1));
swap(colors, l, randomIndex);
int v = colors[l];
int i = l+1;
int j = r;
while(true){
while(i <= r && colors[i]<v)
i++;
while(j >= l+1 && colors[j]>v)
j--;
if(i > j)
break;
swap(colors, i++, j--);
}
swap(colors, l, j);
return j;
}
private void swap(int[] nums, int i, int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}