75. Sort Colors

219 查看

题目:
Given an array with n objects colored red, white or blue, sort them 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.

click to show follow up.

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 an one-pass algorithm using only constant space?

解题:
可以参考EPI的14.8, 这题比较简单,就没有用书里的解法,follow up的思想就是交换,既然只能one pass,那就一次至少搞定一个数啦
解法1:

public void Color(int[] nums, int color, int start, int len) {
        for (int i = start; i < start + len; i++) {
            nums[i] = color;
        }
    }
    public void sortColors(int[] nums) {
        if (nums == null || nums.length == 0) return;
        
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; i++) {
            if (!map.containsKey(nums[i])) {
                map.put(nums[i], 1);
            } else {
                map.put(nums[i], map.get(nums[i]) + 1);
            }
        }
        
        int r = map.get(0) != null ? map.get(0) : 0;
        int w = map.get(1) != null ? map.get(1) : 0;
        int b = map.get(2) != null ? map.get(2) : 0;
        
        Color(nums, 0, 0, r);
        Color(nums, 1, r, w);
        Color(nums, 2, r + w, b);
    }

Follow up解法:

public void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
    
    public void sortColors(int[] nums) {
        if (nums == null || nums.length == 0) return;
        
        int r = 0, b = nums.length - 1;
        for (int i = 0; i < nums.length; i++) {
        //只要是遇到0或者2,就需要采取行动
            while (nums[i] == 0 && i >= r || (nums[i] == 2 && i <= b)) {
                if (nums[i] == 0) {
                    swap(nums, i, r++);
                } else {
                    swap(nums, i, b--);
                }
            }
        }
    }