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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

最长递增子序列_python_算法与数据结构

發(fā)布時(shí)間:2023/11/30 python 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最长递增子序列_python_算法与数据结构 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

???? 周末了,實(shí)驗(yàn)室的網(wǎng)速還是不給力啊,不知道doctors都在干啥,,,最近都在做算法作業(yè),昨天晚上看了一部電影《將愛進(jìn)行到底》,剛打開電影沒多久就聽到了很熟悉的旋律,讓我很是驚訝,這竟然就是電視版的那首主旋律,十幾年過去了,徐靜蕾?gòu)某醭雒]到現(xiàn)在成為了老徐,我也從黃毛丫頭到現(xiàn)在成為了男子漢,浮生若夢(mèng),歲月流沙。將愛電影的主題曲《因?yàn)閻矍椤泛芎寐?#xff0c;王菲的聲音空靈虛無縹緲,與陳奕迅共同演繹了一首溫馨甜蜜的歌曲。

??? 言歸正傳,到算法上來了,最長(zhǎng)遞增子序列問題在這里不再啰嗦了,不懂的自己baidu去,不過我更喜歡google,呵呵。個(gè)人的愛好吧。

??? 最長(zhǎng)遞增子序列有兩種解法,一種是借助前面的LCS算法,另外是本文要寫的另外一種方法。

?? 1.LCS

????? LCS算法比較的是任意兩個(gè)序列的最長(zhǎng)公共子序列,在最長(zhǎng)遞增子序列中,我們將原序列A首先升序排列得到B,然后將A和B求LCS就可以達(dá)到目的。在這里不再贅述,有關(guān)LCS算法,可以參見前面的文章。

?? 2.網(wǎng)上流傳兩種版本的最長(zhǎng)遞增子序列算法,http://hi.baidu.com/newmyl/blog/item/12f15e97ac88b06854fb965d.html連接對(duì)這個(gè)算法進(jìn)行了深入的分析。我個(gè)人比較贊同http://www.felix021.com/blog/read.php?1587&guid=5的分析(http://blog.csdn.net/fisher_jiang/archive/2008/05/13/2442348.aspx也對(duì)這個(gè)算法進(jìn)行了分析但是本人覺得比較晦澀難懂,C++STL我不習(xí)慣,高手自己揣摩吧~~~~),摘錄如下:

假設(shè)存在一個(gè)序列d[1..9] = 2 1 5 3 6 4 8 9 7,可以看出來它的LIS長(zhǎng)度為5。
下面一步一步試著找出它。
我們定義一個(gè)序列B,然后令 i = 1 to 9 逐個(gè)考察這個(gè)序列。
此外,我們用一個(gè)變量Len來記錄現(xiàn)在最長(zhǎng)算到多少了
首先,把d[1]有序地放到B里,令B[1] = 2,就是說當(dāng)只有1一個(gè)數(shù)字2的時(shí)候,長(zhǎng)度為1的LIS的最小末尾是2。這時(shí)Len=1
然后,把d[2]有序地放到B里,令B[1] = 1,就是說長(zhǎng)度為1的LIS的最小末尾是1,d[1]=2已經(jīng)沒用了,很容易理解吧。這時(shí)Len=1
接著,d[3] = 5,d[3]>B[1],所以令B[1+1]=B[2]=d[3]=5,就是說長(zhǎng)度為2的LIS的最小末尾是5,很容易理解吧。這時(shí)候B[1..2] = 1, 5,Len=2
再來,d[4] = 3,它正好加在1,5之間,放在1的位置顯然不合適,因?yàn)?小于3,長(zhǎng)度為1的LIS最小末尾應(yīng)該是1,這樣很容易推知,長(zhǎng)度為2的LIS最小末尾是3,于是可以把5淘汰掉,這時(shí)候B[1..2] = 1, 3,Len = 2
繼續(xù),d[5] = 6,它在3后面,因?yàn)锽[2] = 3, 而6在3后面,于是很容易可以推知B[3] = 6, 這時(shí)B[1..3] = 1, 3, 6,還是很容易理解吧? Len = 3 了噢。
第6個(gè), d[6] = 4,你看它在3和6之間,于是我們就可以把6替換掉,得到B[3] = 4。B[1..3] = 1, 3, 4, Len繼續(xù)等于3
第7個(gè), d[7] = 8,它很大,比4大,嗯。于是B[4] = 8。Len變成4了
第8個(gè), d[8] = 9,得到B[5] = 9,嗯。Len繼續(xù)增大,到5了。
最后一個(gè), d[9] = 7,它在B[3] = 4和B[4] = 8之間,所以我們知道,最新的B[4] =7,B[1..5] = 1, 3, 4, 7, 9,Len = 5。
于是我們知道了LIS的長(zhǎng)度為5。
!!!!! 注意。這個(gè)1,3,4,7,9不是LIS,它只是存儲(chǔ)的對(duì)應(yīng)長(zhǎng)度LIS的最小末尾。有了這個(gè)末尾,我們就可以一個(gè)一個(gè)地插入數(shù)據(jù)。雖然最后一個(gè)d[9] = 7更新進(jìn)去對(duì)于這組數(shù)據(jù)沒有什么意義,但是如果后面再出現(xiàn)兩個(gè)數(shù)字 8 和 9,那么就可以把8更新到d[5], 9更新到d[6],得出LIS的長(zhǎng)度為6。
然后應(yīng)該發(fā)現(xiàn)一件事情了:在B中插入數(shù)據(jù)是有序的,而且是進(jìn)行替換而不需要挪動(dòng)——也就是說,我們可以使用二分查找,將每一個(gè)數(shù)字的插入時(shí)間優(yōu)化到O(logN)~~~~~于是算法的時(shí)間復(fù)雜度就降低到了O(NlogN)~!

個(gè)人覺得他的分析十分清晰明了,真正能讓我們知道動(dòng)態(tài)規(guī)劃算法的過程。按照這種思路,我實(shí)現(xiàn)了Python版本的LIS算法:

#最長(zhǎng)單調(diào)遞增子序列 def LIS(B, d, n):left = right = mid = len = 1B[0] = d[0] # //從0開始計(jì)數(shù)for i in range(1, n):left = 0right = lenwhile(left <= right):mid = (left + right) // 2if(B[mid] < d[i]):left = mid + 1 #二分查找d[i]的插入位置else:right = mid - 1B[left] = d[i] #插入if(left > len) :len = len +1 #更新lengthreturn lenif '__name__ = __main__' :d = [2 , 1 , 5 , 3 , 6, 4, 8, 9, 7] B=[0]*len(d) #初始化B數(shù)組print(LIS(B, d, len(d)))

?

輸出結(jié)果:

Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (Intel)] on CHENX, Threaded
>>> 5

posted on 2011-03-20 22:16 追求卓越 挑戰(zhàn)極限 閱讀(...) 評(píng)論(...) 編輯 收藏

刷新評(píng)論刷新頁面返回頂部

導(dǎo)航

  • 博客園
  • 首頁
  • 新隨筆
  • 聯(lián)系
  • 訂閱
  • 管理

統(tǒng)計(jì)

  • 隨筆 - 27
  • 文章 - 0
  • 評(píng)論 - 21
  • 引用 - 0

公告

轉(zhuǎn)載于:https://www.cnblogs.com/ChenxofHit/archive/2011/03/20/1989760.html

總結(jié)

以上是生活随笔為你收集整理的最长递增子序列_python_算法与数据结构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。