Partition

  1. Kth Largest Element in an Array
  2. Kth Smallest Element in a Sorted Matrix

  3. Sort Colors

  4. Sort Colors II

  5. Sort Letters by Case

  6. 1. Kth Largest Element in an Array

quick sort 的变形

唔,需要好好理解下这道quick sort的变形题。

有好几种解法,根据性能优化来讲。

  1. Arrays.sort + 直接用index来access value: O(N log N) + O(1) memory
  2. Priority Queue with size of K + iterate through the list: O(N log K) + O(k)
  3. quick sort: O(N) best case / O(N^2) worst case running time + O(1) memory
  4. randomized quick sort

重点理解下quick sort + randomized quick sort

2. Kth Smallest Element in a Sorted Matrix

3. Sort Colors

three way partition

需要好好理解下几个Pointer是怎么移动的。

demo可以参考Princeton课件里的dijkstra's 3 way partition

算法公式是

终止条件 i <= right;跟right交换的时候,不需要i ++,其他两种情况都要i ++,因为gt指针是未知元素,需要再判断。

[0, left - 1] 是 < v的元素,[left, i - 1] 是 = v的元素,[i, right] 是未知元素。

4. Sort Colors II

  1. counting sort: O(n) time, O(k) space
  2. sort on each individual colors: O(n^2) time, O(1)
  3. quick sort: O(n log n) time
  4. customized quick sort: O(n log k) time
  • Counting Sort: 因为已经知道了range是[1, k], 所以可以建个k长的array, 数每个元素有多少个,然后再填回去。
public class Solution {
    /**
     * Method I: O(k) space, O(n) time; two-pass algorithm, counting sort
     * @param colors: A list of integer
     * @param k: An integer
     * @return: nothing
     */
    public void sortColors2TwoPass(int[] colors, int k) {
        int[] count = new int[k];
        for (int color : colors) {
            count[color-1]++;
        }
        int index = 0;
        int colorNum = 1;
        for (int occur: count) {
            while (occur > 0) {
                colors[index] = colorNum;
                index++;
                occur--;
            }
            colorNum++;
        }
    }
}
  • Sort on each individual color:

    • 用两个pointers,初始位置为0和length - 1,因为已经知道了range为[1, k],那么每次可以把数字和min & max数字比较,如果在== min || max 之外的话,则swap。
    • each time sort the array into 3 parts: [sorted min array], [unsorted], [sorted max array]
    • [0, left - 1] ,[left, i - 1] ,[i, right]

    • O(n^ 2) = T(n - 2) + n

public class Solution {
    public void sortColorsII(int[] colors, int k) {
        if (colors == null || colors.length <= 1) return;
        int left = 0, right = colors.length - 1;
        int min = 1, max = k;
        int currt = 0;
        while (min < max) {
            //template
            while (currt <= right) {
                if (colors[currt] == min) {
                    swap(colors, currt, left);
                    currt++;
                    left++;
                } else if (colors[currt] == max) {
                    swap(colors, currt, right);
                    right--;
                } else { // within in the range
                    currt++;
                }
            }
            //unsorted subarray starts from the left pointer
            currt = left;
            min++;
            max--;
        }
    }
}
  • Normal Quick Sort
    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     }
  • Customized Quick Sort
// version 1: O(nlogk), the best algorithm based on comparing
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;
        }
        rainbowSort(colors, 0, colors.length - 1, 1, k);
        // sortColorsII(colors, k);
    }

    public void rainbowSort(int[] colors,
                            int left,
                            int right,
                            int colorFrom,
                            int colorTo) {
        if (colorFrom == colorTo) {
            return;
        }

        if (left >= right) {
            return;
        }

        int colorMid = (colorFrom + colorTo) / 2;
        int l = left, r = right;
        while (l <= r) {
            while (l <= r && colors[l] <= colorMid) {
                l++;
            }
            while (l <= r && colors[r] > colorMid) {
                r--;
            }
            if (l <= r) {
                int temp = colors[l];
                colors[l] = colors[r];
                colors[r] = temp;

                l++;
                r--;
            }
        }

        rainbowSort(colors, left, r, colorFrom, colorMid);
        rainbowSort(colors, l, right, colorMid + 1, colorTo);
    }
}

//todo :http://www.cnblogs.com/yuzhangcmu/p/4177326.html

results matching ""

    No results matching ""