算法筆記_051:荷蘭國旗問題(Java)


目錄

1 問題描述

2 解決方案

 


1 問題描述

現有n個紅白藍三種不同顏色的小球,亂序排列在一起,請通過兩兩交換任意兩個球,使得從左至右的球依次為紅球、白球、藍球。這個問題之所以叫荷蘭國旗,是因為將紅白藍三色的小球弄成條狀物,並有序排列后正好組成荷蘭國旗。

 


2 解決方案

為了方便編碼與討論,用數字0表示紅球,數字1表示白球,數字2表示藍球,所以最后生成的排列為0,1,2

解決該問題,只需先設定三個用於指定元素的下標指針(PS:在Java中沒有指針,此處方便描述):一個前指針begin,一個中指針current,一個后指針endCurrent指針遍歷整個數組序列:

(1)current指針所指元素為0時,與begin指針所指的元素交換,而后current++begin++

(2)current指針所指元素為1時,不做任何交換,而后current++

(3)current指針所指元素為2時,與end指針所指的元素交換,而后current指針不動,end--.

那么,為什么在上述第(3)步中,current指針不動?因為如果end所指元素為0時,此時current指針就不能動。

具體代碼如下:

package com.liuzhen.array_2;

public class HollandFlagProblem {
    //輸出荷蘭國旗問題后的排序結果,時間復雜度為O(n),空間復雜度為O(1)
    public void getHollandSort(int[] A){
        int begin = 0;
        int current = 0;
        int end = A.length - 1;
        while(current <= end){
            //值得注意的是:此處if語句是使用if-else if-else if,而沒有使用if-if-if。這樣使用保證每一次循環只執行一個條件,
            //否則,若使用if-if-if,可能會形成一次循環執行兩到三個if條件,造成最終結果錯誤(PS:即在循環結束前,發生current > end)
            if(A[current] == 0){
                swap(A,begin,current);
                begin++;
                current++;
            }
            else if(A[current] == 1)
                current++;    
            else if(A[current] == 2){
                swap(A,current,end);
                end--;
            }
        }
        
        //輸出排完序后的數組A相應元素
        System.out.println("對數組A進行划分后的元素順序為:");
        for(int i = 0;i < A.length;i++)
            System.out.print(A[i]+" ");
    }
    
    //交換數組A中m位置和n位置上元素的值
    public void swap(int[] A,int m,int n){
        int temp = A[m];
        A[m] = A[n];
        A[n] = temp;
    }
    
    public static void main(String[] args){
        HollandFlagProblem test = new HollandFlagProblem();
        int[] A = {2,0,2,0,0,2,1,1,0,2,1,0,1,2,0,1,2,0,1,0,2,1,0,2,0,1,2,0,1,2,0,2,1,0};
        test.getHollandSort(A);
    }
}

運行結果:

對數組A進行划分后的元素順序為:
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 

 

 

 

參考資料:

   1.《編程之法面試和算法心得》   July 著


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM