力扣75——顏色分類

原題

給定一個包含紅色、白色和藍(lán)色,一共 n 個元素的數(shù)組,原地對它們進(jìn)行排序,使得相同顏色的元素相鄰,并按照紅色、白色、藍(lán)色順序排列。

此題中,我們使用整數(shù) 0、 1 和 2 分別表示紅色、白色和藍(lán)色。

注意:

不能使用代碼庫中的排序函數(shù)來解決這道題。

示例:

輸入: [2,0,2,1,1,0]
輸出: [0,0,1,1,2,2]

進(jìn)階:

* 一個直觀的解決方案是使用計數(shù)排序的兩趟掃描算法。
首先,迭代計算出0、1 和 2 元素的個數(shù),然后按照0、1、2的排序,重寫當(dāng)前數(shù)組。
* 你能想出一個僅使用常數(shù)空間的一趟掃描算法嗎?

原題url:https://leetcode-cn.com/problems/sort-colors/

解題

兩趟掃描

我當(dāng)時想到的第一種想法就是排序,后來感覺沒有必要,因為只有3種元素,我完全就可以按照進(jìn)階提示中的第一條,先掃描統(tǒng)計出各元素個數(shù),然后第二遍掃描時,直接進(jìn)行賦值。

讓我們直接來看代碼:

class Solution {
    public void sortColors(int[] nums) {
        // 記錄0,1,2的個數(shù)
        int num0 = 0, num1 = 0, num2 = 0;
        // 計算各個數(shù)字出現(xiàn)的次數(shù)
        for (int i : nums) {
            switch(i) {
                case 0:
                    num0++;
                    break;
                case 1:
                    num1++;
                    break;
                case 2:
                    num2++;
                    break;
            }
        }
        // 重新賦值
        for (int i = 0; i < nums.length; i++) {
            if (i < num0) {
                nums[i] = 0;
            } else if (i < num0 + num1) {
                nums[i] = 1;
            } else {
                nums[i] = 2;
            }
        }
    }
}

提交OK,執(zhí)行用時:0 ms,內(nèi)存消耗:35.2 MB。是否還可以優(yōu)化呢?

優(yōu)化

參考進(jìn)階提示中的第二條,上面的方法使用了常數(shù)空間,但一遍掃描該如何做到呢?

我其實并沒有想出來,參考了別人的解法:利用三個指針進(jìn)行一次遍歷并交換。

具體來說,就是增加一個當(dāng)前指針current(從下標(biāo)0開始)、一個指向數(shù)字0區(qū)間的末尾指針p0(從下標(biāo)0開始)、一個指向數(shù)字2區(qū)間的開始指針p2(從下標(biāo) nums.length - 1)。下標(biāo)0 到下標(biāo) p0 之間存放數(shù)字0,下標(biāo) p0 到 p2 之間存放數(shù)字1,下標(biāo) p2 到 下標(biāo) (nums.length - 1) 之間存放數(shù)字2。current 指針從下標(biāo)0開始遍歷,如果值為0,則和 p0 交換,如果值為2,則和 p2 交換。

讓我們來看看代碼:

class Solution {
    public void sortColors(int[] nums) {
        // 利用3個指針current、p0、p2
        int current = 0, p0 = 0, p2 = nums.length - 1;
        while (current <= p2) {
                    // 如果當(dāng)前值為1,current指針往后移動
            if (nums[current] == 1) {
                current++;
                continue;
            }
                        
                        // 如果當(dāng)前值為0,則和 p0 交換,p0指針往后移動
            if (nums[current] == 0) {
                nums[current] = nums[p0];
                nums[p0] = 0;
                                // 因為p0一開始和current相同
                if (p0 == current) {
                    current++;
                }
                p0++;
                continue;
            }

                        // 如果當(dāng)前值為2,則和 p2 交換,p2指針往前移動
            if (nums[current] == 2) {
                nums[current] = nums[p2];
                nums[p2] = 2;
                p2--;
                continue;
            }
        }
    }
}

提交OK,執(zhí)行用時:0 ms,內(nèi)存消耗:35 MB。這結(jié)果,感覺好像沒有多少優(yōu)化,但對于我們而言,最重要的是增加了一種解題思路。

總結(jié)

以上就是這道題目我的解答過程了,不知道大家是否理解了。這道題主要在于利用指針一遍掃描得出結(jié)果,優(yōu)化解題。

有興趣的話可以訪問我的博客或者關(guān)注我的公眾號、頭條號,說不定會有意外的驚喜。

https://death00.github.io/

公眾號:健程之道

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 題目 給定一個包含紅色、白色和藍(lán)色,一共 n 個元素的數(shù)組,原地對它們進(jìn)行排序,使得相同顏色的元素相鄰,并按照紅色...
    禾木清清閱讀 390評論 0 0
  • 數(shù)組中重復(fù)的數(shù)字(一維數(shù)組) 問題:在一個長度為長度為n的數(shù)組里的所有數(shù)字都在0-n-1之間。找出任意一個重復(fù)的數(shù)...
    Drama_Du閱讀 1,240評論 0 0
  • 數(shù)據(jù)結(jié)構(gòu)是算法的基石,如果沒有扎實的數(shù)據(jù)結(jié)構(gòu)基礎(chǔ),想要把算法學(xué)好甚至融會貫通是非常困難的,而優(yōu)秀的算法又往往取決于...
    layjoy閱讀 880評論 0 1
  • 外面烈日高照,路上行人匆匆。 她舔了舔干裂的嘴唇,摸了摸干癟的口袋:只剩1塊5毛錢了。 路邊開了家“武大郎燒餅店”...
    麥田守望_范閱讀 233評論 0 0
  • 我一直是個作文白癡。 想到什么,如果用文字的方式表達(dá)出來?;剡^頭我再去看自己寫的東西,總感覺怪怪的,哪里不通順,哪...
    冊冊閱讀 639評論 0 2

友情鏈接更多精彩內(nèi)容