LeetCode—75—Sort Colors(三路快排思想應(yīng)用)

題目

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

Example:

Input: [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]

翻譯

給定一個數(shù)組,包含n個元素懈凹,n個元素被隨機(jī)標(biāo)記了三種顏色的一種荤西,紅色滓技,白色猪狈,藍(lán)色∥蓿現(xiàn)在原地排序括儒,使相同顏色的元素相鄰茧痒,按照紅色肮韧,白色,藍(lán)色的順序排列旺订。在這里我們分別用0惹苗,1,2耸峭。代表三種顏色桩蓉。

解題思路

通過題意可知,這個數(shù)組有其特殊性劳闹,特點就是數(shù)組只包含三種元素院究。所以首先提供一種暴力的解法。就是分別統(tǒng)計每個元素在數(shù)組中出現(xiàn)了多少次本涕。然后根據(jù)元素在數(shù)組中出現(xiàn)的次數(shù)业汰,將數(shù)組重新賦值。
代碼如下:

// 75. Sort Colors
// https://leetcode.com/problems/sort-colors/description/
//
// 計數(shù)排序的思路
// 對整個數(shù)組遍歷了兩遍菩颖,第一遍統(tǒng)計各個元素個數(shù)样漆,第二遍將數(shù)組重新賦值
// 時間復(fù)雜度: O(n)
// 空間復(fù)雜度: O(k), k為元素的取值范圍
public class Solution1 {

    public void sortColors(int[] nums) {

        int[] count = {0, 0, 0};    // 存放0, 1, 2三個元素的頻率
        for(int i = 0 ; i < nums.length ; i ++){
            assert nums[i] >= 0 && nums[i] <= 2;
            count[nums[i]] ++;
        }

        int index = 0;
        for(int i = 0 ; i < count[0] ; i ++)
            nums[index++] = 0;
        for(int i = 0 ; i < count[1] ; i ++)
            nums[index++] = 1;
        for(int i = 0 ; i < count[2] ; i ++)
            nums[index++] = 2;
    }
}

優(yōu)化解法

在這里我們可以采用三路快排的思想,什么是三路快排呢晦闰,三路快排就是在數(shù)組中選擇一個標(biāo)定點放祟,然后以這個標(biāo)定點為依據(jù)鳍怨,將數(shù)組分為三部分,小于標(biāo)定點的數(shù)據(jù)跪妥,等于標(biāo)定點的數(shù)據(jù)鞋喇,和大于標(biāo)定點的數(shù)據(jù)。然后在小于標(biāo)定點和大于標(biāo)定點的區(qū)域繼續(xù)采用三路快排的思想排序眉撵,就是一個遞歸調(diào)用的過程侦香。對于本題,因為只有三種元素纽疟,所以一次調(diào)用就完成了整個排序過程罐韩。我們先來看幾張圖。


無標(biāo)題.png

在這里我們新定義兩個索引zero,two污朽。當(dāng)我們遍歷數(shù)組時散吵,將0元素放到[0...zero]區(qū)間,將為2的元素放到區(qū)間[zero..n-1]中膘壶。


1.png

由上圖可知错蝴,此時我們遍歷到第i個元素洲愤。第i個元素值為2颓芭,我們就將第i個元素的值放到two-1的位置。同時將two-1位置的元素放到i的位置柬赐。就是交換這兩個位置的元素亡问。因為找出為2的元素增加了一個,所以two要減一肛宋。而此時i是不變的州藕,因為交換過來的數(shù)據(jù)是啥仍然是未知的。同理可以分析出當(dāng)?shù)趇個元素如果是0和1要應(yīng)該怎么處理酝陈。具體情況請看代碼床玻。
// 75. Sort Colors
// https://leetcode.com/problems/sort-colors/description/
//
// 三路快速排序的思想
// 對整個數(shù)組只遍歷了一遍
// 時間復(fù)雜度: O(n)
// 空間復(fù)雜度: O(1)
public class Solution2 {

    public void sortColors(int[] nums) {
   // [0...zero] == 0,初始情況zero為-1沉帮,此時區(qū)間無效锈死。
   //如果初始值為1,那就是說區(qū)間中第一個元素是0,
   //而第一個元素未知穆壕,所以這里初始值設(shè)為-1待牵;
        int zero = -1;       
        int two = nums.length;  // [two...n-1] == 2,同理初始區(qū)間是無效區(qū)間
        for(int i = 0 ; i < two ; ){
            if(nums[i] == 1)
                i ++;
            else if (nums[i] == 2)
                swap(nums, i, --two);   //two先自減
            else{ // nums[i] == 0
                assert nums[i] == 0;
                swap(nums, ++zero, i++);    //zero先自增
            }
        }
    }

    private void swap(int[] nums, int i, int j){
        int t = nums[i];
        nums[i]= nums[j];
        nums[j] = t;
    }
}

更多內(nèi)容歡迎大家關(guān)注

yuandatou
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市喇勋,隨后出現(xiàn)的幾起案子缨该,更是在濱河造成了極大的恐慌,老刑警劉巖川背,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贰拿,死亡現(xiàn)場離奇詭異蛤袒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)壮不,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門汗盘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人询一,你說我怎么就攤上這事隐孽。” “怎么了健蕊?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵菱阵,是天一觀的道長。 經(jīng)常有香客問我缩功,道長晴及,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任嫡锌,我火速辦了婚禮虑稼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘势木。我一直安慰自己蛛倦,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布啦桌。 她就那樣靜靜地躺著溯壶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪甫男。 梳的紋絲不亂的頭發(fā)上且改,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機(jī)與錄音板驳,去河邊找鬼又跛。 笑死,一個胖子當(dāng)著我的面吹牛若治,可吹牛的內(nèi)容都是我干的慨蓝。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼直砂,長吁一口氣:“原來是場噩夢啊……” “哼菌仁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起静暂,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤济丘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摹迷,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡疟赊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了峡碉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片近哟。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鲫寄,靈堂內(nèi)的尸體忽然破棺而出吉执,到底是詐尸還是另有隱情,我是刑警寧澤地来,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布戳玫,位于F島的核電站,受9級特大地震影響未斑,放射性物質(zhì)發(fā)生泄漏咕宿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一蜡秽、第九天 我趴在偏房一處隱蔽的房頂上張望府阀。 院中可真熱鬧,春花似錦芽突、人聲如沸试浙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽川队。三九已至力细,卻和暖如春睬澡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背眠蚂。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工煞聪, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人逝慧。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓昔脯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親笛臣。 傳聞我的和親對象是個殘疾皇子云稚,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容