75 - Sort Colors

75 - Sort Colors

https://www.youtube.com/watch?v=yTwW8WiGrKw

 

75, sort colors, rainbow sort .. sort k colors

 

Sort colors 

Solution one:
// counting sort 
class Solution {
    public void sortColors(int[] nums) {
        int zero = 0;
        int one = 0;
        int two = 0;
        for(int num : nums){
            if(num == 0) zero++;
            if(num == 1) one++;
            if(num == 2) two++;
        }
        
        
        for(int i = 0; i < nums.length; i++){
            if(zero > 0){         // use while wrong! 
                nums[i] = 0;
                zero--;
                
            }else if (one > 0){      // use while wrong ! 
                nums[i] = 1;
                one--; 
            }else{                 // use while wrong ! 
                nums[i] = 2;
                two--;
                
            }         

        }
    }
}



Solution two: one pass


class Solution {
    public void sortColors(int[] nums) {
        int i = 0;
        int j = 0;
        int k = nums.length - 1;
        while(j <= k){
            if(nums[j] == 2){
                swap(nums, j, k);
                k--;
            }else if(nums[j] == 1){
                j++;
            }else{
                // nums[j] == 0
                swap(nums, i, j);
                j++;// necessary here 
                i++;
            }
        }
    }
    private void swap(int[] nums, int i, int j){
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}



Input:
[2,0,1]
Output:
[1,0,2]
Expected:
[0,1,2]
走一下这个例子, 就知道为什么 while(j <= k), 而不是 j < k . 




                swap(nums, i, j);
                j++;// necessary here 
                i++;

If we don’t have j++, the result looks like this 
Your input
[2,0,2,1,1,0]
Your answer
[1,1,2,2,0,0]







https://www.youtube.com/watch?v=yTwW8WiGrKw

public void SortColors(int[] nums){
  if(nums == null || nums.length <= 1){
    return;
  }
  
  int i = 0;
  int j = 0; 
  int k = nums.length - 1;
  
  while(j <= k){
    if(nums[j] == 'a'){
      swap(nums, i++, j++);
    }else if(nums[j] == 'b'){
      j++;
    }else{
      swap(nums, j, k--);
    }
  }
}


private void swap(int[] nums, int i, int j){
  int tmp = nums[i];
  nums[i] = nums[j];
  nums[j] = tmp;
}






Sort k colors 
https://aaronice.gitbooks.io/lintcode/content/high_frequency/sort_colors_ii.html


Question
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.



Analysis
简单的办法可以利用two pass, 相当于counting sort,计数每个color的个数,再依次填入到原来的array中;这种方法空间复杂度为 O(k), 时间复杂度为 O(n)。
第二种则是利用两个指针的方法,设定pl和pr,左右两个指针,初始位置分别为数组两端,pl = 0, pr = colors.length - 1. 同时,由于题目限制条件,已知min和max,因此可以据此作为比较,来决定如何移动pl,pr两个指针。不断对满足min和max条件的colors进行swap,就可以在in-place的条件下,做到sorting colors,这种算法的空间复杂度为O(1), 而时间复杂度:这种方法的时间复杂度为O(n^2): T(n) = T(n - 2) + n。

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;
        for (int i = 0; i < k; i++) {
            while (count[i]>0) {
                colors[index++] = i+1;
                count[i]--;
            }
        }
    }



 /**
     * Method II:
     *  Each time sort the array into three parts:
     *  [all min] [all unsorted others] [all max],
     *  then update min and max and sort the [all unsorted others]
     *  with the same method.
     *
     * @param colors: A list of integer
     * @param k: An integer
     * @return: nothing
     */
    public void sortColors2(int[] colors, int k) {
        int pl = 0;
        int pr = colors.length - 1;
        int i = 0;
        int min = 1, max = k;
        while (min < max) {
            while (i <= pr) {
                if (colors[i] == min) {
                    swap(colors, pl, i);
                    i++;
                    pl++;
                } else if (colors[i] == max) {
                    swap(colors, pr, i);
                    pr--;
                } else {
                    i++;
                }
                // printArray(colors);
            }
            i = pl;
            min++;
            max--;
        }
    }

    private void swap(int[] colors, int i, int j) {
        int temp = colors[i];
        colors[i] = colors[j];
        colors[j] = temp;
    }

    public static void main(String[] args) {
        Solution s = new Solution();
        int[] colors = new int[]{2, 5, 3, 4, 2, 2, 1};
        int k = 5;
        s.sortColors2(colors, k);
    }
    private static void printArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
        System.out.print("\n");
    }
}

 

Given an array with n objects colored red, white or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white and blue.

Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.

Note: You are not suppose to use the library's sort function for this problem.

Example:

Input: [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]

Follow up:

    • A rather straight forward solution is a two-pass algorithm using counting sort.
      First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's.
    • Could you come up with a one-pass algorithm using only constant space?

posted on 2018-08-09 17:22  猪猪&#128055;  阅读(138)  评论(0)    收藏  举报

导航