日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法64-荷兰国旗问题

發布時間:2024/8/1 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法64-荷兰国旗问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目:

給定一個數組,如[1,2,3,2,3,2,1,2,3,2,1],給出一個int=2,這個值必須存在數組中,要求將數組中的元素按小于int的值在左邊,等于int的值在中間,大于的在右邊

問題來源:

分析:

在說 “荷蘭國旗” 問題之前,首先來看一個引例。

給定一個數組arr,和一個數num,請把小于等于num的數放在數組的左邊,大于num的數放在數組的右邊。要求額外空間復雜度O(1),時間復雜度 O(N)
分析: 設定一個小于等于區,從0開始比較,如果當前數字小于等于num ,讓其與小于等于區的下一個值做交換,再將小于等于區擴大一位,直到將所有的數字都與num進行過比較。重新排好的數組就是所求的數組。如下給出示意過程:


最終就可以得到一個在num左邊所有的數都小于等于num右邊都大于num。
這個過程實際上可以看成是小于等于區域在推著大于等于區域向右走,而當遇到小于等于num的數時,進行的操作是,與大于區域的第一個數字做交換,這聽起來就有些像堆排序的heapify過程。

荷蘭國旗問題(直觀的“分三塊”的問題)
—— 有了上面這些問題的基礎,荷蘭國旗問題就會好想一些。

給定一個數組arr,和一個數num,請把小于num的數放在數組的左邊,等于num的數放在數組的中間,大于num的數放在數組的右邊。要求額外空間復雜度O(1),時間復雜度O(N)
分析: 上一個題目要求將數組分成兩塊,而這個是將數組分成三塊。上一個問題是在左邊設置了一個大于等于區,這個問題可以在左邊設置一個小于區,在右邊設置一個大于區,不斷向中間逼近,最終中間就是相等的數字。操作過程也和上一個問題是完全一樣的。如下過程所示:


有了上面的分析,代碼就很容易理解

代碼:

package mainimport ("fmt"// "math"// "sort"// "time" )func partition(list []int,num int) []int{more:=len(list)less:=-1index:=0for index < more{// fmt.Println("here")if list[index]<num{fmt.Printf("exchange idex %v less %v ",index+1,less+1)swap(list,index,less+1)less++index++//小于去必然小于等于index,將一個小于num的的數放進小于區,不會引起小于區的混亂,//小于去已經是檢查過的區域,必然符合規則,不用重新檢測index位置}else if list[index]>num{fmt.Printf("exchange idx %v more %v ",index,more-1)swap(list,index,more-1)more--//大于區的數未知,放到index位置的話可能引起混亂,所以index不推進,從當前index繼續檢測}else{//等于什么都不做,,所以不會引起任何混亂,直接推進index檢查下一位index++}fmt.Println(index)fmt.Println(list)}fmt.Println(less+1,more-1)result:=[]int{less+1,more-1}return result }func swap(list []int,m,n int){tmp:=list[m]list[m]=list[n]list[n]=tmp } func main(){// list:=[]int{15, 11, 53, 2, 14, 4, 25, 27, 45, 0,30,99,2}list:=[]int{1,2,3,1,2,3,2,1,2,3,2,1,2,2}partition(list,2)}}

總結:
1 此方法類似快排的思想,但又有所不同
2 重點在于小于 等于 大于 三種條件的處理完全不同

  • 小于-因為小于區是已經排好的,并且當前index指向的值已經知道是小于的,而且index的范圍,相當于小于等于區,交換實質是將小于等于區的數與小于等于區的數交換,交換后還是小于等于區,并不會引起混亂,所以直接index++推進
  • 等于-index的指針就是等于區的邊界,所以無需交換,推進index
  • 大于-因為大于區的數是未知的,將當前index的數與大于區的數交換,交換過來的數有可能是大于或是小于的,因此index不能推進,要進入下一次循環重新檢測index的值

less小于區,index實際相當于小于等于區

完全理解了上面的邏輯,coding才能進行下去,在此詳細記錄

參考

總結

以上是生活随笔為你收集整理的算法64-荷兰国旗问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。