左神演算法課程系列--荷蘭國旗問題
【題目】
荷蘭國旗問題
已知一個整型陣列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工程師成神之路一文中介紹的所有知識點。 程式設計屆有一句老話,叫做不要重複造輪子。雖然我並不完全認同這句