Given an array of n objects with k different colors (numbered from 1 to k), sort them so that objects of the same color are adjacent, with the colors in the order 1, 2, ... k.
Example
Example1
Input:
[3,2,2,1,4]
4
Output:
[1,2,2,3,4]
Example2
Input:
[2,1,1,2,2]
2
Output:
[1,1,2,2,2]
Challenge
A rather straight forward solution is a two-pass algorithm using counting sort. That will cost O(k) extra memory. Can you do it without using extra memory?
Notice
- You are not suppose to use the library's sort function for this problem.
k
<=n
思路:按照quick sort的思想来,start, end是数组起点,终点的范围,from to 是颜色的范围,用颜色的中间值,作为pivot,然后小的在左边,大的在右边,先整体有序,再局部有序;注意 start >= end || from >= to base条件的判断,还有midcolor属于左边;
public class Solution {
/**
* @param colors: A list of integer
* @param k: An integer
* @return: nothing
*/
public void sortColors2(int[] colors, int k) {
if(colors == null || colors.length == 0) {
return;
}
int n = colors.length;
quickSelect(colors, 0, n - 1, 1, k);
}
private void quickSelect(int[] colors, int start, int end, int from, int to) {
if(start >= end || from >= to) { // 注意这个base条件的判断,否则出错;
return;
}
int midcolor = from + (to - from) / 2;
int i = start; int j = end;
while(i <= j) {
// midcolor 属于左边;
while(i <= j && colors[i] <= midcolor) {
i++;
}
while(i <= j && colors[j] > midcolor) {
j--;
}
if(i <= j) {
int temp = colors[i];
colors[i] = colors[j];
colors[j] = temp;
i++;
j--;
}
}
// j , i;
quickSelect(colors, start, j, from, midcolor); // midcolor属于左边;
quickSelect(colors, i, end, midcolor + 1, to);
}
}