Given an array of n objects with k different colors (numbered from 1 to K), sort them so, objects of the same Color is adjacent, with the colors in the order 1, 2, ... k.
Note
You is not a suppose to use the library's sort function for this problem.
Example
GIven colors=[3, 2, 2, 1, 4], k=4, your code should sort colors In-place to [1, 2, 2, 3, 4].
Challenge
A rather straight forward solution is a two-pass algorithm using counting sort. That would cost O (k) extra memory.
Can do it without using extra memory?
Analysis:
Sort:o (NLOGN), quick or merge.
O (n): Use the array itself as space to store counts. We use A[k-1] to store the count of color K. We use negtive number to store count, in order to is distnct with the color value. This method assumes that every color between 1 and K would appear.
At position I, we check the value of a[a[i]-1], if it was A positive number, i.e., not counted yet, we then put A[a[i]-1] t o A[i], and set a[a[i]-1] as-1 to indicate that there are one of this color.
If A[a[i]-1] is A negtive or zero value, we then simply decrease it by one and set A[i] as 0 to indicate the this Positio N is couted already.
At position I, we repeat this procedure until a[i] becomes 0 or negtive, we and move to i+1.
At counting, we draw the colors into array.
Solution:
1 classSolution {2 /**3 * @paramcolors:a List of integers4 * @paramK:an integer5 * @return: Nothing6 */7 Public voidSortColors2 (int[] Colors,intk) {8 //The method assumes that every color much appear in the array.9 intLen =colors.length;Ten if(len<k)return; One A //Count the number of each color. - for(inti=0;i<len;i++){ - while(colors[i]>0){ the intKey = Colors[i]-1; - if(colors[key]<=0){ -colors[key]--; -Colors[i]=0; +}Else { -Colors[i] =Colors[key]; +Colors[key] = 1; A } at } - } - - //draw colors. - intindex = len-1; - intCInd = k-1; in while(cind>=0){ - intnum =Math.Abs (Colors[cind]); to for(inti=0;i<num;i++){ +Colors[index]=cind+1; -index--; the } *cind--; $ }Panax Notoginseng } -}
Lintcode-sort Colors II