1. 程式人生 > >左神演算法課程系列--荷蘭國旗問題

左神演算法課程系列--荷蘭國旗問題

code技巧的磨練

【題目】
荷蘭國旗問題
已知一個整型陣列arr,和一個整數num,請把小於num的數放在陣列的左邊,等於num的數放在陣列的中間,大於num的數放在陣列的右邊。

要求:時間複雜度為O(N),額外空間複雜度O(1)。

這個題目應該很多人是想到排序的,但排序的話,需要O(N log(N))的時間複雜度,最糟的時候是O(N^2)。但題目並沒要我們進行排序,仔細思考一下,其實確實不需要,O(N)的時間複雜度就可以搞定了:假定有一個左區域,一個右區域,左區域在陣列下標為0的左邊,右區域在陣列下標為arr.length-1的右邊,當前位置為i,當i位置的數小於給定數字的時候,i位置的數和小於區域的下一個數交換,i下移一位。當等於時,i直接下移,當大於時,i位置的數和大於區域的前一個數交換,這時i位置不移動,因為剛交換過來的數還不知道大小,所以應該先判斷,而需要指向下一個。

(雖然這些程式碼我上完課都寫了,但還是放左神的程式碼的,加點註釋)

public class Code_01_NetherlandsFlag {

 	//演算法核心程式碼:
	public static int[] partition(int[] arr, int l, int r, int num) {
		//less,more 分別是少於和大於的區域指標
		int less = l - 1;
		int more = r + 1;
		int i = l;//i是當前位置
		while (i < more) {
			//當前位置的數如果少於P就和少於區域的下一個交換
			//如果大於P就和大於區域的前一個交換
			//如果等於就直接跳到下一個
			if (arr[i] < num) {
				swap(arr, ++less, i++);
			} else if (arr[i] > num) {
				swap(arr, --more, i);//因為剛交換過來的數還不知道大小,所以應該先判斷,而需要指向下一個
			} else {
				i++;
			}
		}
		return new int[] { less + 1, more - 1 };
	}

	// for test
	public static void swap(int[] arr, int i, int j) {
		int tmp = arr[i];
		arr[i] = arr[j];
		arr[j] = tmp;
	}

	// for test
	public static int[] generateArray() {
		int[] arr = new int[10];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = (int) (Math.random() * 3);
		}
		return arr;
	}

	// for test
	public static void printArray(int[] arr) {
		if (arr == null) {
			return;
		}
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " ");
		}
		System.out.println();
	}

	public static void main(String[] args) {
		int[] test = generateArray();//產生一個隨機陣列

		printArray(test);//列印陣列
		int[] res = partition(test, 0, test.length - 1, 1);//陣列,起始位置,終止位置
		printArray(test);
		System.out.println(res[0]);//返回的是等於num的陣列的起始位置和終止位置
		System.out.println(res[1]);

	}
}


相關推薦

演算法課程系列--荷蘭國旗問題

code技巧的磨練 【題目】 荷蘭國旗問題 已知一個整型陣列arr,和一個整數num,請把小於num的數放在陣列的左邊,等於num的數放在陣列的中間,大於num的數放在陣列的右邊。要求:時間複雜度為O(N),額外空間複雜度O(1)。 這個題目應該很多人是想到排序的,但排序的

演算法初級02——荷蘭國旗問題、隨機快速排序、堆排序、桶排序、相鄰兩數的最大差值問題、工程中的綜合排序演算法

主要討論:荷蘭國旗問題、隨機快速排序、堆排序、穩定性、比較器、桶排序、相鄰兩數的最大差值問題和簡單介紹工程中的綜合排序演算法   題目一 給定一個數組arr,和一個數num,請把小於等於num的數放在陣列的左邊,大於num的數放在陣列的右邊。 要求額外空間複雜度O(1),時間複雜度O(N)

面試常考演算法題(二)--荷蘭國旗問題

面試常考演算法題(二)–荷蘭國旗問題 荷蘭國旗問題是面試中常考的一個題目,涉及到的思想並不是很複雜. 荷蘭國旗問題 題目 給定一個數組arr,和一個數num,請把小於num的數放在陣列的左邊,等於num的數放在陣列的中間,大於num的數放在陣列的右邊。 要求

演算法初級02——荷蘭國旗問題、隨機快速排序、堆排序

public static void heapSort(int[] arr) { if (arr == null || arr.length < 2) { return; } for (int i = 0; i <

牛客演算法題1.1

題目:有一排正數,玩家A和玩家B都可以看到。 每位玩家在拿走數字的時候,都只能從最左和最右的數中選擇一個。 玩家A先拿,玩家B再拿,兩人交替拿走所有的數字, 兩人都力爭自己拿到的數的總和比對方多。請返回最後獲勝者獲勝的最小分數 (PS:原題最後一句話

算法系列--荷蘭國旗問題

【問題】 現有紅白藍三個不同顏色的小球,亂序排列在一起,請重新排列這些小球,使得紅白藍三色的同顏色的球在一起。這個問題之所以叫荷蘭國旗問題,是因為我們可以將紅白藍三色小球想象成條狀物,有序排列後正好組成荷蘭國旗。 【分析】 這個問題我們可以將這

04.堆排序 --- HeapSort(演算法基礎班原始碼)

package basic_class_01; import java.util.Arrays; /** * * 堆排序的細節和複雜度分析 * 時間複雜度O(N*logN),額外空間複雜度O(1) * 堆結構非常重要 1,堆結構的heapInsert與heap

演算法基礎班4_4_3在二叉樹中找到一個節點的後繼節點

Problem:   在二叉樹中找到一個節點的後繼節點   【題目】 現在有一種新的二叉樹節點型別如下:   public class Node {   public int value;   public Node left;   public Node right;   public No

第八課之遞迴演算法

題目一 求n! 簡單得不想說 題目二 漢諾塔問題 古代有一個梵塔,塔內有三個座A、B、C,A座上有64個盤子,盤子大小不等,大的在下,小的在上(如圖)。有一個和尚想把這64個盤子從A座移到C座,但每次只能允許移動一個盤子,並且在移動過程中,3個座上的盤子始終

演算法之(一)荷蘭國旗問題

通過一次劃分,將陣列分為三部分,前半段為小於num的數,中間半段為等於num的數,後半段為大於num的數 public static void partition(int[] arr, int num) { int less = -1; int more

荷蘭國旗演算法及其拓展

一排木桶裡分別裝有紅白藍三色小球(分別用0,1,2表示),如何讓所有的'0'出現在前面,所有的'1'在中間,所有的'2'在最後。 要求:要求空間複雜度為O(1),只許遍歷一遍字串陣列。 之所以叫荷蘭國旗,是因為我們可以將紅白藍三色小球想象成條狀物,有序排列後正好組成荷蘭國旗

面試演算法整理---單調棧

【題目】 小B負責首都的防衛工作。 首都處於一個四面環山的盆地中,周圍的n個小山構成一個環,作為預警措施,小B計劃在每個小山上設定一個觀察哨,日夜不停的瞭望周圍發生的情況。 一旦發生外敵入侵事件,山頂上的崗哨將點燃烽煙。 若兩個崗哨所在的山峰之間的那些山峰,高度都不大於這兩

01-樹的 層序遍歷

-1 images cnblogs com log nbsp .com 分享 mage 左神01-樹的 層序遍歷

編程之法:面試和算法心得(荷蘭國旗

數組排列 alt partition void 不同 begin 心得 不能 sta 內容全部來自編程之法:面試和算法心得一書,實現是自己寫的使用的是java 題目描述 拿破侖席卷歐洲大陸之後,代表自由,平等,博愛的豎色三色旗也風靡一時。荷蘭國旗就是一面三色旗(只不過是橫向

75. Sort Colors(荷蘭國旗問題 三指針)

resp order 問題 row them clas pre spa use Given an array with n objects colored red, white or blue, sort them so that objects of the

帶你刷題之生成窗口最大值數值

pack 生成 inf get -i int arr AI OS 題目描述:   有一個整型數組arr和一個大小為w的窗口從數組的最左邊滑到最右邊,窗口每次向右滑動一個位置。 比如 : 給定數組【4 3 5 4 3 3 6 7】 【4 3 5 】4 3 3 6 7

SSE影象演算法優化系列二十四: 基於形態學的影象後期抗鋸齒演算法--MLAA優化研究。

       偶爾看到這樣的一個演算法,覺得還是蠻有意思的,花了將近10天多的時間研究了下相關程式碼。        以下為百度的結果:MLAA全稱Morphological Antialiasing,意為形態抗鋸齒是AMD推出

#二分、二叉樹# 一節公開課的題解

題目1:二分查詢區域性最小值   Description: 定義區域性最小的概念。arr 長度為1時,arr[0] 是區域性最小。arr的長度為 N(N > 1) 時,如果 arr[0] < arr[1],那麼 arr[0] 是區域性最小;如果 arr[N-1]

SSE影象演算法優化系列二十三: 基於value-and-criterion structure 系列濾波器(如Kuwahara,MLV,MCV濾波器)的優化。 SSE影象演算法優化系列十四:區域性均方差及區域性平方差演算法的優化 SSE影象演算法優化系列七:基於SSE實現的極速的矩形核腐蝕和膨脹(

       基於value-and-criterion structure方式的實現的濾波器在原理上其實比較簡單,感覺下面論文中得一段話已經描述的比較清晰了,直接貼英文吧,感覺翻譯過來反而失去了原始的韻味了。        T

《成之路系列文章》

Java工程師成神之路一文介紹了一個普通的Java工程師想要成神需要學習的所有相關知識點。很多內容介紹都是直接拋了一個連結,並且大部分都是英文文件或者相關技術的官網。 本系列文章主要從頭開始總結Java工程師成神之路一文中介紹的所有知識點。 程式設計屆有一句老話,叫做不要重複造輪子。雖然我並不完全認同這句