原題連接: http://lintcode.com/zh-cn/problem/sort-colors-ii/#java
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.git
You are not suppose to use the library's sort function for this problem.
github
GIven colors=[3, 2, 2, 1, 4], k=4, your code should sort colors in-place to [1, 2, 2, 3, 4]. 算法
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?ide
使用快排,時間複雜度是O(nlogn),空間複雜度是O(Log(N))ui
1 /** 2 * @param colors: A list of integer 3 * @param k: An integer 4 * @return: nothing 5 */ 6 /* 7 Solution 1: Using the quick sort. 8 */ 9 public void sortKColors1(int[] colors, int k) { 10 // write your code here 11 if (colors == null) { 12 return; 13 } 14 15 quickSort(colors, 0, colors.length - 1); 16 } 17 18 public void quickSort(int[] colors, int left, int right) { 19 if (left >= right) { 20 return; 21 } 22 23 int pivot = colors[right]; 24 25 int pos = partition(colors, left, right, pivot); 26 27 quickSort(colors, left, pos - 1); 28 quickSort(colors, pos + 1, right); 29 } 30 31 public int partition(int[] colors, int left, int right, int pivot) { 32 int leftPoint = left - 1; 33 int rightPoint = right; 34 35 while (true) { 36 while (colors[++leftPoint] < pivot); 37 38 while (leftPoint < rightPoint && colors[--rightPoint] > pivot); 39 40 if (leftPoint >= rightPoint) { 41 break; 42 } 43 44 swap(colors, leftPoint, rightPoint); 45 } 46 47 swap(colors, leftPoint, right); 48 return leftPoint; 49 } 50 51 public void swap(int[] colors, int left, int right) { 52 int tmp = colors[left]; 53 colors[left] = colors[right]; 54 colors[right] = tmp; 55 }
inplace,而且O(N)時間複雜度的算法。this
咱們能夠使用相似桶排序的思想,對全部的數進行計數。spa
1. 從左掃描到右邊,遇到一個數字,先找到對應的bucket.好比code
3 2 2 1 4
第一個3對應的bucket是index = 2 (bucket從0開始計算)
2. Bucket 若是有數字,則把這個數字移動到i的position(就是存放起來),而後把bucket記爲-1(表示該位置是一個計數器,計1)。
3. Bucket 存的是負數,表示這個bucket已是計數器,直接減1. 並把color[i] 設置爲0 (表示此處已經計算過)
4. Bucket 存的是0,與3同樣處理,將bucket設置爲-1, 並把color[i] 設置爲0 (表示此處已經計算過)
5. 回到position i,再判斷此處是否爲0(只要不是爲0,就一直重複2-4的步驟)。
6.完成1-5的步驟後,從尾部到頭部將數組置結果。(從尾至頭是爲了不開頭的計數器被覆蓋)
例子(按以上步驟運算):
3 2 2 1 4
2 2 -1 1 4
2 -1 -1 1 4
0 -2 -1 1 4
-1 -2 -1 0 4
-1 -2 -1 -1 0
1 // Solution 2: inplace, O(n) 2 public void sortKColors(int[] colors, int k) { 3 // write your code here 4 if (colors == null) { 5 return; 6 } 7 8 int len = colors.length; 9 for (int i = 0; i < len; i++) { 10 // Means need to deal with A[i] 11 while (colors[i] > 0) { 12 int num = colors[i]; 13 if (colors[num - 1] > 0) { 14 // 1. There is a number in the bucket, 15 // Store the number in the bucket in position i; 16 colors[i] = colors[num - 1]; 17 colors[num - 1] = -1; 18 } else if (colors[num - 1] <= 0) { 19 // 2. Bucket is using or the bucket is empty. 20 colors[num - 1]--; 21 // delete the A[i]; 22 colors[i] = 0; 23 } 24 } 25 } 26 27 int index = len - 1; 28 for (int i = k - 1; i >= 0; i--) { 29 int cnt = -colors[i]; 30 31 // Empty number. 32 if (cnt == 0) { 33 continue; 34 } 35 36 while (cnt > 0) { 37 colors[index--] = i + 1; 38 cnt--; 39 } 40 }
https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/lintcode/array/SortKColors.java