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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《算法图解》笔记与总结

發(fā)布時間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《算法图解》笔记与总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?寫在開頭

這是一篇讀書筆記式的文章,力求簡要地概括《算法圖解》 中陌生和重要的內(nèi)容,所以有的具體內(nèi)容仍需要參考原書。

值得記錄的代碼附在文末,使用python編寫。

持續(xù)更新。

這本書已經(jīng)讀完,這篇筆記也更新至此。不得不說,《算法圖解》是一本對新手非常友好的書,內(nèi)容詳細而不啰嗦,十分有條理,只要沿著順序讀下去,基本能夠很快理解消化。我很慶幸我是在這本書中第一次接觸到諸如動態(tài)規(guī)劃之類的知識點,否則很有可能又被勸退了。當(dāng)然,由于其篇幅限制,很多常用內(nèi)容沒有介紹到,還需要繼續(xù)補充,這些內(nèi)容記錄在我的另一篇筆記里。


第1章 算法簡介

二分查找

大O表示法:O(n),n指操作數(shù)

  • 該表示法中的log默認以2為底
  • 指出了算法運行時間的增速
  • 畫16個格子的例子:一個一個畫,O(n);四次對折,O(logn)
  • 指出的是最糟情況下的操作數(shù)

常見的大O運行時間

  • O(log n)
  • O(n)
  • O(n*log n)
  • O(n^2)
  • O(n!),如旅行商問題

隨著輸入的增加,上述五種算法的操作數(shù)的增加由慢到快


第2章 選擇排序

數(shù)組與鏈表的區(qū)別:“挨著坐”和“分開坐”

數(shù)組在內(nèi)存中是連續(xù)存放的;鏈表中的元素可以存儲在內(nèi)存的任何地方,鏈表的每個元素都存儲了下一個元素的地址。

數(shù)組vs鏈表

  • 當(dāng)數(shù)組增加元素而相鄰內(nèi)存單元已被占用,就需要移動整個數(shù)組,鏈表不存在這個問題
  • 需要讀取鏈表最后一個元素時,需要從第一個開始依次讀取。當(dāng)需要同時讀取所有元素時,鏈表效率高,需要跳躍時效率低;數(shù)組相反
  • 數(shù)組支持隨機訪問,鏈表只能順序訪問

一個疑惑和其解答

Q:在向鏈表的中間插入元素時,不需要先從第一個元素逐個獲取索引,直到要插入的位置?

A:獲取索引即讀的過程,不應(yīng)算在操作數(shù)中;只考慮插入這個操作。

數(shù)組與列表可以組合使用

facebook存儲用戶信息的例子

TODO:選擇排序的例子,為什么是使用平均每次檢查的操作數(shù)的平均值來計算O,而不是直觀理解的階乘?


第3章 遞歸

性能

遞歸并不會比循環(huán)提高性能,但可能更容易理解

組成

  • 基線條件:控制何時停止調(diào)用自己,避免無限循環(huán)
  • 遞歸條件:循環(huán)調(diào)用自己

只對最上層元素執(zhí)行兩種操作:插入、刪除并讀取(彈出)

調(diào)用棧

例子的文字總結(jié):一個函數(shù)A中調(diào)用了另一個函數(shù)B,當(dāng)A開始執(zhí)行,內(nèi)存分配給其一部分,存儲其涉及到的所有變量;當(dāng)執(zhí)行到B,內(nèi)存分配給B一部分,并在棧中壓在A的部分之上;執(zhí)行B,其被從棧上彈出,此時A位于最上方,故繼續(xù)執(zhí)行A。這個用于儲存多個函數(shù)的變量的棧,被稱為調(diào)用棧。

調(diào)用另一個函數(shù)時,當(dāng)前函數(shù)暫停并處于未完成狀態(tài)。

遞歸調(diào)用棧:以階乘為例

要注意,一個變量在每次調(diào)用中的值可能不同,在一個調(diào)用中不能訪問另一個調(diào)用中的變量(還是比較符合常識的)

棧的弊端

每次函數(shù)調(diào)用會占用內(nèi)存,棧過高占用的內(nèi)存也過多

解決辦法:改用循環(huán);使用尾遞歸(本書不涉及)


第4章 快速排序

分而治之,Divide and Conquer,D&C

  • 找出盡可能簡單的基線條件
  • 不斷將問題分解直到滿足基線條件

Tip:涉及到數(shù)組的遞歸函數(shù)常見的基線條件是數(shù)組為空或只含一個元素。

快速排序思路

  • 最簡單的排序:不需要排序,即數(shù)組中只有0或1個元素
  • 兩個元素的數(shù)組,比較二者的值
  • 多于兩個元素的數(shù)組,分而治之
    • 選取一個元素作為基準值(暫取第一個)
    • 分區(qū):遍歷,找出比基準值大的和小的元素,分別構(gòu)成兩個數(shù)組。目前有:比基準值小的子數(shù)組、基準值、比基準值大的子數(shù)組
    • 對子數(shù)組遞歸,直到剩下的數(shù)組長度小于等于二
    • 子數(shù)組排序后,合并

????????使用python實現(xiàn)的快排,見代碼1

再談大O表示法 - 比較合并排序和快速排序 -?大O表示法中的常量

例子,逐個打印數(shù)組元素的函數(shù),一個沒有sleep(1)(記一次sleep的時間為c),另一個有,則其運行時間分別為c*n和n。但是在大O表示法中,固定時間量,也即常數(shù)c,是忽略不計的,因為一般來說對時間影響更大的是n和logn的區(qū)別。

對于運行時間都為nlogn的快速查找和合并查找,常量的影響就可能很大;快速查找更快,因為其遇上最糟情況的可能性比平均情況低得多。

平均情況和最糟情況

以快速排序的基準值為例,當(dāng)基準始終選擇在開頭時(最糟情況),調(diào)用棧會非常長,O(n);而當(dāng)基準選擇在中間(最佳情況),調(diào)用棧就短得多,O(log n)。

取一個元素為基準值,并劃分數(shù)組的操作,不論基準值取在了哪里,劃分了多少組,都涉及到了n(數(shù)組長度)個元素,即每次調(diào)用棧的操作時間都為O(n)。

最佳情況的層數(shù)O(log n),每層操作時間O(n),所以總時間O(nlog n);最糟情況層數(shù)O(n),所以總時間O(n^2)。

只要每次的基準值都是隨機選擇,快速排序的平均運行時間就是O(nlog n);也就是說,最佳情況也是平均情況?-?這里不求甚解了:(


第5章 散列(Hash)表

散列函數(shù)

將輸入映射到數(shù)字

  • 必須:一致性:對同樣的輸入,映射的數(shù)字必須相同
  • 理想但不必須:對于不同的輸入,映射到不同的數(shù)字

Maggie的例子

創(chuàng)建一個用于存儲物價的空列表

蘋果->散列函數(shù)->輸出一個數(shù)字->列表中這個數(shù)字的位置存儲著蘋果的價格

該例子中散列函數(shù)的性質(zhì):

  • 輸入相同,輸出就相同
  • 輸入不同,輸出就不同
  • 只返回有效的輸出,如列表長度為5,就不會返回索引為100

散列表:散列函數(shù)+數(shù)組

一種包含額外邏輯的數(shù)據(jù)結(jié)構(gòu),由鍵和值組成。

數(shù)組和鏈表都被直接映射到內(nèi)存,但散列表使用散列函數(shù)來確定元素的存儲位置。

散列表獲取元素的速度和數(shù)組一樣快。

Python的字典就是散列表。

散列表的應(yīng)用

  • 查找,eg:電話薄
  • 避免重復(fù),eg:投票
  • 緩存,eg:Facebook,當(dāng)URL在散列表中時,發(fā)送緩存中的數(shù)據(jù),否則讓服務(wù)器處理。如此加快了加載速度,并減輕了服務(wù)器負擔(dān)

沖突?

存儲apple和avocardo的價格的例子:能夠總是將不同的鍵映射到不同值的散列函數(shù)難以實現(xiàn)。

不同的鍵被分配給了同一個值,即沖突。

最簡單的解決辦法,在該位置創(chuàng)建鏈表,依次存儲,但是性能不佳。

理想的情況是,散列函數(shù)將鍵均勻映射到散列表的不同位置。一個好的散列函數(shù)很重要。

常量時間O(1)

散列表在平均情況下的操作時間為O(1),不意味著馬上,而是不論散列表多大,所需時間都相同。

散列表的性能

平均情況下,散列表的查找(獲取給定索引處的值)速度與數(shù)組一樣快,而插入和刪除速度與鏈表一樣快,兼具兩者的優(yōu)點。但在最糟情況,即有沖突的情況下,散列表的各種操作的速度都很慢。

選讀:散列表的實現(xiàn) 避開最糟情況

避免沖突的方式

  • 較低的填裝因子:元素數(shù)/位置總數(shù),越低越不容易沖突
  • 良好的散列函數(shù):讓數(shù)組中的值均勻分布

第6章 廣度優(yōu)先搜索 圖 樹

廣度優(yōu)先搜索:尋找解決問題的最短路徑的問題,用于圖的查找算法

圖由節(jié)點組成。一個節(jié)點可能與眾多節(jié)點直接相連,稱為鄰居。

兩類問題

  • 從節(jié)點A出發(fā),有前往節(jié)點B的路徑嗎?eg:朋友中有無芒果銷售商
  • 從節(jié)點A出發(fā),前往節(jié)點B的哪條路徑最短?eg:朋友中哪個芒果銷售商關(guān)系最近

?在名單中依次檢查,如果當(dāng)前人(一度關(guān)系)不是銷售商,就把他的朋友加入到相應(yīng)的關(guān)系部分(二度關(guān)系)(隊列的末尾)。實現(xiàn)“依次”,需要數(shù)據(jù)結(jié)構(gòu):隊列。如果不是依次的,找到的就可能不是最短路徑。

隊列

隊列,先進先出,First In First Out,FIFO

棧,后進先出,Last In First Out,LIFO

在python中

  • 創(chuàng)建雙端隊列:q =?deque()
  • 向隊列添加元素:q += item(可以是數(shù)組以一次添加多個)
  • 彈出第一個元素:item = q.popleft()

使用散列表實現(xiàn)圖

找銷售商的例子,創(chuàng)建一個字典,以graph["you"] = ["alice", "bob", "claire"]、graph["alice"] = ["peggy"]的形式添加,即以一人為鍵,其下級關(guān)系的所有人的數(shù)組為值。由于散列表是無序的,所以添加內(nèi)容的順序也沒有影響。

有向圖:關(guān)系是單向的,eg:有從別人指向Anuj的箭頭,但沒有從Anuj指向別人的箭頭,所以Anuj沒有鄰居

無向圖:沒有箭頭,直接相連的節(jié)點互為鄰居

在銷售商例子中,由于一個人可能同時是多個人的朋友,為了避免重復(fù)檢查無限循環(huán),在檢查完一個人后,應(yīng)將其標記為已檢查,且不再檢查他。

運行時間

在整個人際關(guān)系網(wǎng)中搜索芒果銷售商,意味著將沿每條邊前行,因此運行時間至少為O(邊數(shù));

使用了一個隊列,將一個人添加到隊列需要的時間是固定的,O(1),因此總時間為O(人數(shù));

所以,廣度優(yōu)先搜索的運行時間為O(V+E),其中V為頂點數(shù),E為邊數(shù)。

一種特殊的圖,其中沒有往后指的邊

如果任務(wù)A依賴于任務(wù)B,在列表中任務(wù)A就必須在任務(wù)B后面。這被稱為拓撲排序,使用它可根據(jù)圖創(chuàng)建一個有序列表。

合理的順序:

  • 起床 - 刷牙 - 吃早餐 - 洗澡
  • 起床 - 刷牙 - 洗澡 - 吃早餐(即吃早餐必須在刷牙后,但不一定緊挨著)

第7章?狄克斯特拉算法

加權(quán)圖:帶權(quán)重的圖。否則是非加權(quán)圖。

例子:由起點到終點,每一段都有相應(yīng)的時間(權(quán)重)。廣度優(yōu)先搜索找出的是段數(shù)最少的路徑,狄克斯特拉可用于找出最快(總權(quán)重最小)的路徑。換言之,廣度優(yōu)先搜索找出的是非加權(quán)圖的最短路徑,狄克斯特拉找出的是加權(quán)圖的最短路徑。

適用范圍:沒有負權(quán)邊的有向無環(huán)圖

步驟

  • 初始化:所有節(jié)點的開銷(從起點到改節(jié)點的最小權(quán)重)為無窮大,節(jié)點的父節(jié)點未知
  • 起點的鄰居中,找出開銷小的節(jié)點A,并將A的父節(jié)點設(shè)為起點
  • 更新A的所有鄰居的開銷,如果某鄰居C的開銷被更新,就說明沿著經(jīng)過A的路徑是開銷最小的,所以將C的父節(jié)點更新為A
  • 將A標記為已分析
  • 重復(fù)2、3、4,繼續(xù)分析除A以外開銷最小的節(jié)點,更新其所有鄰居的開銷和父節(jié)點,直到除了終點外的所有節(jié)點都被分析
  • 根據(jù)父節(jié)點可倒推得開銷最短的路徑
  • 環(huán)

    從某節(jié)點走一圈后又回到該節(jié)點。繞環(huán)的路徑不可能是最短路徑。

    無向圖意味著兩個節(jié)點彼此指向?qū)Ψ?#xff0c;其實就是環(huán),在無向圖中,每條邊都是一個環(huán)。

    狄克斯特拉算法只適用于有向無環(huán)圖。

    負權(quán)邊

    即權(quán)重為負的邊。

    狄克斯特拉算法假設(shè):對于處理過的海報節(jié)點,沒有前往該節(jié)點的更短路徑。 這種假設(shè)僅在沒有負權(quán)邊時才成立。在琴譜換鋼琴的例子中,已經(jīng)更新過經(jīng)由海報的路徑,但如果有負權(quán)邊,就相當(dāng)于找到了前往海報的更短路徑,而在狄克斯特拉算法中,經(jīng)由海報的路徑已經(jīng)更新并不再改變,所以無法正常更新。

    不能將狄克斯特拉算法用于包含負權(quán)邊的圖。可以用貝爾曼-福德算法(略)。

    代碼實現(xiàn)

    需要三個散列表和一個數(shù)組,用于:

    • graph:記錄鄰居關(guān)系和權(quán)重(兩層)
    • costs:更新開銷(從起點到該節(jié)點的總權(quán)重)
    • parents:更新父節(jié)點
    • processed = []:記錄已經(jīng)處理的節(jié)點

    代碼實現(xiàn)見代碼2


    第8章 貪婪算法

    有些情況下,完美是優(yōu)秀的敵人

    排課問題與背包問題

    一間教室,課的時間有沖突,選出盡可能多且時間不沖突的課程。

    • 選出結(jié)束最早的課作為要在這間教室上的第一堂課
    • 選擇第一堂課結(jié)束后才開始的課。同樣選擇結(jié)束最早的課作為第二堂課,如此重復(fù)

    每步都選擇局部最優(yōu)解,最終得到的就是全局最優(yōu)解

    但同樣的思路不適用于另一個例子,背包問題:容量35的背包,要裝下價值最大的東西,可以裝的有重量30價值3000的音響、重量20價值2000的筆記本、重量15價值1500的吉他。如果按照上面的思路,先裝入最值錢的音響,就無法再裝入別的東西,價值比筆記本+吉他少。

    集合覆蓋問題

    例子:需要讓節(jié)目被全美50個州的聽眾都收聽得到,在每個廣播臺播出都需要支付費用,因此力圖在盡可能少的廣播臺播出。每個廣播臺都覆蓋特定的區(qū)域,不同廣播臺的覆蓋區(qū)域可能重疊。即需要找出覆蓋全美50個州的最小廣播臺集合。

    窮舉法列出所有可能的集合,子集有2**n個。

    需要使用近似算法:

    • 選出覆蓋了最多的未覆蓋州的一個廣播臺(不考慮它覆蓋了多少已覆蓋的)
    • 重復(fù)直到覆蓋所有州

    該例子的python代碼,見代碼3

    NP完全問題

    簡單定義是,以難解著稱的問題,如旅行商問題和集合覆蓋問題。有觀點認為不可能編寫出可快速解決NP完全問題的算法。

    如果能判斷出一個問題是不是NP完全問題,就可以決定是否采用貪心算法。不存在判斷標準,但可以根據(jù)問題的特征判斷:

    • 元素較少時算法的運行速度非常快,但隨著元素數(shù)量的增加,速度會變得非常慢
    • 涉及“所有組合”的問題
    • 不能將問題分成小問題,必須考慮各種可能的情況
    • 涉及序列(如旅行商問題中的城市序列)且難以解決
    • 涉及集合(如廣播臺集合)且難以解決
    • 可轉(zhuǎn)換為集合覆蓋問題或旅行商問題,那它肯定是NP完全問題

    第9章 動態(tài)規(guī)劃

    目的:將某個指標最大化。

    背包問題,窮舉太復(fù)雜,貪心算法可能找出的不是最優(yōu)解。需要使用動態(tài)規(guī)劃。

    動態(tài)規(guī)劃先解決子問題,再逐步解決大問題。

    以背包問題為例介紹動態(tài)規(guī)劃

    背包容量4磅,音響3000美元4磅,筆記本電腦2000美元3磅,吉他1500美元1磅。

    每個動態(tài)規(guī)劃算法都從一個網(wǎng)格開始。表格列標題為容量(不同容量的子背包),行為可選擇的商品,每個格子用于記錄當(dāng)前能夠裝下的最高價值和其對應(yīng)的組合。每一行的格子考慮當(dāng)前行所代表的商品和當(dāng)前行以上的商品,如:第一行,就只能裝吉他;第二行只能裝音響和吉他,不能考慮筆記本電腦。

    ?目的是讓背包中商品的價值最大,計算每一行時,該行都表示的是當(dāng)前的最大價值。

    更新到第一行時,最大價值是吉他1500美元。

    更新完第一行后的最大價值 更新完第二行后的最大價值 標題?更新完第二行后的最大價值

    ?在最后一個單元格,如果偷單價最高的音響,則3000美元;但如果選擇筆記本電腦(當(dāng)前行所讀應(yīng)的),則2000美元,剩下的1磅空間再偷吉他,總共3500美元。

    其實在每一個單元格,都使用了如下公式計算價值,對應(yīng)上圖的紅色框。

    ?注意cell[i-1][j-當(dāng)前商品重量]中的[i-1]而不是[i]因為,i代表本行商品,已經(jīng)裝入。

    特性

    • 在不改變表格列的粒度時,增加商品,不需要重新計算表格,往下繼續(xù)算即可;
    • 行的排列順序不影響最終結(jié)果;
    • 每列從上到下,價值不可能減小;
    • 要么考慮拿走整件商品,要么考慮不拿,而沒法判斷該不該拿走商品的一部分(拿一部分應(yīng)該用貪心);
    • 僅當(dāng)每個子問題都是離散的,即不依賴于其他子問題時,動態(tài)規(guī)劃才管用(旅行規(guī)劃為例);
    • 大背包至多含有兩個子背包,但子背包可能又含有子背包;
    • 最優(yōu)解可能出現(xiàn)在背包沒裝滿的情況;
    標題當(dāng)增加一個重量為0.5的商品項鏈時,需要調(diào)整表格的粒度,重新計算?

    以尋找最長公共子串為例應(yīng)用動態(tài)規(guī)劃

    最長公共子串要求在原字符串中是連續(xù)的,而子序列只需要保持相對順序一致,并不要求連續(xù)

    用戶輸入HISH,備選單詞FISH、VISTA

    Tips:

    • 每種動態(tài)規(guī)劃解決方案都涉及網(wǎng)格;
    • 單元格中的值通常就是要優(yōu)化的值。在前面的背包問題中,單元格的值為商品的價值;
    • 每個單元格都是一個子問題,因此應(yīng)考慮如何將問題分成子問題,這有助于找出網(wǎng)格的坐標軸

    ?對于尋找最長公共子串問題

    • 單元格中的值即需要優(yōu)化的值:最長公共子串的長度
    • 橫坐標,輸入單詞
    • 縱坐標,可能匹配的單詞
    • 逐行計算,當(dāng)cell[i][j]的i和j對應(yīng)的字母不同,則該單元格為0;當(dāng)相同,該單元格為1+cell[i-1][j-1]
    • 整個表格填充完后尋找表格中的最大值

    對于尋找最長公共子序列問題

    • 當(dāng)兩字母相同時,值為左上角加1,這點比較好理解
    • 當(dāng)兩字母不同時,值為上方和左側(cè)中值大的,這是為了保存當(dāng)前已經(jīng)尋找到的最長子序列的長度,如此才能使下一次找到兩個相同字母時,其左上角的值是正確的

    ?沒有放之四海皆準的計算動態(tài)規(guī)劃解決方案的公式.


    第10章 KNN

    非常簡要地介紹了KNN、推薦系統(tǒng)、OCR等,因為已經(jīng)了解且這里介紹的太基礎(chǔ),所以不詳細記錄。


    第11章 What's next

    這一章也語焉不詳,不作記錄。

    樹:B樹,紅黑樹,堆,伸展樹

    反向索引;傅里葉變換;并行算法,mapreduce;概率型算法-布隆過濾器和HyperLogLog;安全散列算法SHA;Diffie-Hellman密鑰;線性規(guī)劃。


    代碼

    代碼1 Python實現(xiàn)快排

    def q_sort(l):if len(l) == 2:if l[0] > l[1]:return [l[1], l[0]]else:return lelif len(l) == 1 or len(l) == 0:return lelse:base_num = l[0]bigger_l = []smaller_l = []for i in l:if i < base_num:smaller_l.append(i)elif i > base_num:bigger_l.append(i)return q_sort(smaller_l) + [base_num] + q_sort(bigger_l)

    代碼2? 使用狄克斯特拉算法找到權(quán)重最短的路徑和其權(quán)重值

    # 創(chuàng)建圖 graph = {} graph['Start'] = {} graph['Start']['A'] = 5 graph['Start']['B'] = 0 graph['A'] = {} graph['A']['C'] = 15 graph['A']['D'] = 20 graph['B'] = {} graph['B']['C'] = 30 graph['B']['D'] = 35 graph['C'] = {} graph['C']['End'] = 20 graph['D'] = {} graph['D']['End'] = 10inf = float("inf")cost = {} parents = {} processed = [] # 原本是遍歷graph的鍵,將其作為cost的鍵,并將值都設(shè)為inf,但是這種初始化不方便程序開始,所以手動初始化第一步的鄰居 cost['A'] = 5 cost['B'] = 0 cost['C'] = inf cost['D'] = inf cost['End'] = inf parents['A'] = 'Start' parents['B'] = 'Start' parents['C'] = None parents['D'] = None parents['End'] = None# 尋找開支最小的節(jié)點 def find_min_node(cost, processed):temp = max(cost.values())node = Nonefor k in cost:if k not in processed and cost[k] <= temp:node = ktemp = cost[k]return node if node else None #都處理過就返回None# 算法 Node = find_min_node(cost=cost, processed=processed) # 尋找最便宜節(jié)點 while Node:if Node == 'End':breakfor k in graph[Node]:temp_cost = cost[Node] + graph[Node][k]if temp_cost < cost[k]:cost[k] = temp_costparents[k] = Nodeprocessed.append(Node)Node = find_min_node(cost=cost, processed=processed)def p_path(e): # 遞歸打印路徑,因為時間倉促,沒有仔細研究邊界條件,所以不會打印最后的‘End’if e in parents.keys():print('^\n' + parents[e])return p_path(parents[e])print('*'*10 + "\nCost:{c}\n".format(c=cost['End']) + '*'*10) print('End') p_path('End')''' 結(jié)果: ********** Cost:35 ********** End ^ D ^ A ^ Start'''

    代碼3 使用貪婪算法解決集合覆蓋問題

    states = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] # 州 r = {} # 廣播臺 r['r1'] = ['A', 'C', 'F'] r['r2'] = ['B', 'C', 'D'] r['r3'] = ['C', 'E', 'G'] r['r4'] = ['A', 'G']s = set(states) covered = set() r_selected = []while s - covered: # 還有未覆蓋的k_selected = Nonel_temp = 0for k in r: # 尋找能覆蓋最多未覆蓋地區(qū)的頻道if k not in r_selected:temp = (s - covered) & set(r[k]) # 該頻道能覆蓋的未覆蓋地區(qū)數(shù)if len(temp) > l_temp:l_temp = len(temp)k_selected = kcovered = covered | set(r[k_selected])r_selected.append(k_selected) print(r_selected)

    總結(jié)

    以上是生活随笔為你收集整理的《算法图解》笔记与总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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