這道題也是數組操作的題目,其實就是要將數組排序,只是知道數組中只有三個元素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)(如果顏色種類是已知的話)。這道題我覺得主要還是熟悉一下計數排序,計數排序是線性排序中比較重要的一種,關於排序要搞個專題專門的複習一下,很多排序的基本思想都對解題有幫助哈。