Sort Colors -- LeetCode

原題鏈接: http://oj.leetcode.com/problems/sort-colors/ 
這道題也是數組操作的題目,其實就是要將數組排序,只是知道數組中只有三個元素0,1,2。熟悉計數排序的朋友可能很快就發現這其實就是使用計數排序,元素空間只需要三個元素即可。代碼如下: 
public void sortColors(int[] A) {
    if(A==null || A.length==0)
        return;
    int[] res = new int[A.length];
    int[] helper = new int[3];
    for(int i=0;i<A.length;i++)
    {
        helper[A[i]]++;
    }
    for(int i=1;i<3;i++)
    {
        helper[i]=helper[i]+helper[i-1];
    }
    for(int i=A.length-1;i>=0;i--)
    {
        res[helper[A[i]]-1] = A[i];
        helper[A[i]]--;
    }
    for(int i=0;i<A.length;i++)
    {
        A[i] = res[i];
    }
}
上面的代碼是計數排序的標準解法,可以看到總共進行了三次掃描,其實最後一次只是把結果數組複製到原數組而已,如果不需要in-place的結果只需要兩次掃描。
其實就算返回元素組也可以是兩次掃描,這需要用到元素只有0,1,2的本質。我們知道helper[i]中是包含着0,1,2的元素數量,我們只需要按照helper[0,1,2]的數量依次賦值過來即可(每層循環把helper[i]--,如果helper[i]到0就i++就可以了),只是這樣就不是計數排序比較標準的解法,我希望還是複習一下。
這種方法的時間複雜度是O(2*n),空間是O(k),k是顏色的數量,這裏是3。
上述方法需要兩次掃描,我們考慮怎麼用一次掃描來解決。其實還是利用了顏色是三種這一點,道理其實也簡單,就是搞兩個指針,一個指在當前0的最後一個下標,另一個是指在當前1的最後一個下標(2不需要指針因爲剩下的都是2了)。進行一次掃描,如果遇到0就兩個指針都前進一步並進行賦值,如果遇到1就後一個指針前進一步並賦值。代碼如下: 
public void sortColors(int[] A) {
    if(A==null || A.length==0)
        return;
    int idx0 = 0;
    int idx1 = 0;
    for(int i=0;i<A.length;i++)
    {
        if(A[i]==0)
        {
            A[i] = 2;
            A[idx1++] = 1;
            A[idx0++] = 0;
        }
        else if(A[i]==1)
        {
            A[i] = 2;
            A[idx1++] = 1;
        }
    }
}
上述方法時間複雜度還是O(n),只是只需要一次掃描,空間上是O(1)(如果顏色種類是已知的話)。
這道題我覺得主要還是熟悉一下計數排序計數排序是線性排序中比較重要的一種,關於排序要搞個專題專門的複習一下,很多排序的基本思想都對解題有幫助哈。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章