LeetCode Sort Colors (One Pass Solution)

来源:互联网 发布:路由器mac地址是什么 编辑:程序博客网 时间:2024/05/03 04:38

LeetCode - Sort Colors

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.

思路分析:这题很简单,但是要做到O(N)的时间复杂度,并且只用constant 内存不容易,O(N)解决方案有桶排序和Counting Sort,前者需要O(N)的额外空间,后者只需要constant内存。这里给出基于Counting Sort的AC code。

AC Code:
public class Solution {    public void sortColors(int[] A) {        //Implement counting sort        int count1 = 0;         int count2 = 0;         int count0 = 0;        for(int i = 0; i < A.length; i++){            if(A[i] == 2){                count2++;            } else if(A[i] == 1){                count1++;                swap(A, i , i-count2);            } else {                count0++;                swap(A, i, i-count2);                swap(A, i-count2, i-count2-count1);            }        }    }        public void swap(int[] A, int i, int j){        int temp;        temp = A[i];        A[i] = A[j];        A[j] = temp;    }}

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?

思路分析:Follow up的问题要求提出一个one pass的算法,并且是常数空间。事实上上面给出的解法已经满足这一要求,题目里面描述的算法是一个非常naive的算法,先计数0 1 2的个数,然后overwrite数组,但是需要two pass。one pass的思路除了上面的解法之外,还可以基于双指针做,具体做法是定义两个指针p0和p2,移动p0和p2的方式是guarantee p0的左边全是0,p2的右边全是2,这样我们只需要看中间部分。用i来遍历中间部分(即从0开始,到p2结束,注意p2会改变),如果A[i]=0,我们交换A[i]和A[p0];如果A[i]=2,我们交换A[i]和A[p2];如果A[i]=1,则什么也不做继续向前。注意交换之前要check两点:第一 当前的p0和p2不能越界;第二交换的两个index不要相等,否则没必要交换;最后一个trick地方是,交换到中间的数要重新用i检查一次,如果是0或者2也需要特殊处理,因此交换后i--;这也是为什么当index相等时我们不做交换,因为如果不做判断,这里i--会引入bug,要保证i始终在 p2>=i>=p0的范围内。这题思考时一定要想清楚设计p0,p2和i三个指针的作用,范围和移动方法,实现时要特别小心,一个大原则是p0左边全是0,p2右边全是2,i在p0和p2中间检查数做交换。这题调试花了很长时间,关键还是要把算法想清楚,才能消灭bug。
AC Code
public class Solution {    public void sortColors(int[] A) {        if(A.length < 2) return;        int p0, p2;        p0 = 0;        p2 = A.length - 1;        for(int i = 0; i < p2 + 1; i++){            if(A[i] == 0){                if(p0 >= A.length - 1) return;                if(i == p0) continue;                swap(A, i, p0);                p0++;                i--;                continue;            }            if(A[i] == 2){                if(p2 <= 0) return;                if(i == p2) continue;                swap(A, i, p2);                p2--;                i--;                continue;            }        }    }            public void swap(int A[], int i, int j){        int temp = A[i];        A[i] = A[j];        A[j] = temp;    }}



0 0
原创粉丝点击