數(shù)據(jù)結(jié)構(gòu)與算法之美筆記

1.基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)類(lèi)型

(1)線性結(jié)構(gòu)

數(shù)組屯蹦、鏈表殊校、棧民效、隊(duì)列

(2)非線性結(jié)構(gòu)

樹(shù)区岗、圖

2.數(shù)據(jù)結(jié)構(gòu)變體

數(shù)組擴(kuò)展:散列表(散列表用的是數(shù)組支持按照下標(biāo)隨機(jī)訪問(wèn)數(shù)據(jù)的特性)
鏈表擴(kuò)展:跳表
樹(shù)擴(kuò)展:二叉樹(shù)(二叉查找樹(shù)、平衡二叉樹(shù)眠菇、紅黑樹(shù)边败、堆)、Trie樹(shù)

3.各種數(shù)據(jù)結(jié)構(gòu)適用場(chǎng)景或算法應(yīng)用

(1)數(shù)組

數(shù)組需要分配連續(xù)的內(nèi)存空間捎废,對(duì)內(nèi)存有較大要求笑窜,但是可以利用CPU的緩存機(jī)制,查詢(xún)執(zhí)行速度快于鏈表登疗。

(2)鏈表

不需要分配連續(xù)的內(nèi)存空間怖侦,但需要保存指針。和數(shù)組相比谜叹,鏈表更適合插入匾寝、刪除操作頻繁的場(chǎng)景,查詢(xún)的時(shí)間復(fù)雜度較高荷腊。

鏈表加多級(jí)索引的結(jié)構(gòu)艳悔,就是跳表。跳表可以支持快速的插入女仰、刪除猜年、查找。單鏈表插入疾忍、刪除乔外、查找一個(gè)數(shù)據(jù)時(shí)間復(fù)雜度是O(N),跳表能做到O(logN)一罩,相當(dāng)于基于單鏈表實(shí)現(xiàn)了二分查找杨幼。
但比起鏈表要多O(N)的空間復(fù)雜度,不過(guò)索引結(jié)點(diǎn)只需要存儲(chǔ)關(guān)鍵值和幾個(gè)指針,并不需要存儲(chǔ)對(duì)象差购。所以當(dāng)存儲(chǔ)對(duì)象比索引結(jié)點(diǎn)大很多時(shí)四瘫,索引占用的額外空間就可以忽略了。

(3)棧

特性
棧是后進(jìn)先出欲逃、先進(jìn)后出的找蜜。常見(jiàn)應(yīng)用于函數(shù)調(diào)用。

實(shí)現(xiàn)方式
棧既可以用數(shù)組來(lái)實(shí)現(xiàn)稳析,也可以用鏈表來(lái)實(shí)現(xiàn)洗做。用數(shù)組實(shí)現(xiàn)的棧叫作順序棧,用鏈表實(shí)現(xiàn)的棧叫作鏈?zhǔn)綏?/strong>彰居。

(4)隊(duì)列

隊(duì)列是“先進(jìn)先出”的诚纸。

隊(duì)列有基于鏈表(鏈?zhǔn)疥?duì)列)和基于數(shù)組(順序隊(duì)列)這兩種實(shí)現(xiàn)方式。

隊(duì)列可以應(yīng)用在線程池請(qǐng)求排隊(duì)的場(chǎng)景裕菠,還可以應(yīng)用在任何有限資源池中,用于排隊(duì)請(qǐng)求闭专,比如數(shù)據(jù)庫(kù)連接池等奴潘。對(duì)于大部分資源有限的場(chǎng)景,當(dāng)沒(méi)有空閑資源時(shí)影钉,基本上都可以通過(guò)“隊(duì)列”這種數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn)請(qǐng)求排隊(duì)画髓。

(5)樹(shù)

①二叉樹(shù)

二叉樹(shù)重要的操作是前、中平委、后序遍歷操作奈虾。二叉樹(shù)中比較特殊的樹(shù)是完全二叉樹(shù)和滿(mǎn)二叉樹(shù),滿(mǎn)二叉樹(shù)是完全二叉樹(shù)的一種特殊情況廉赔。二叉樹(shù)存儲(chǔ)可以使用鏈?zhǔn)酱鎯?chǔ)或者數(shù)組存儲(chǔ)肉微,完全二叉樹(shù)適合使用數(shù)組存儲(chǔ)

二叉查找樹(shù)是二叉樹(shù)最常用的一種類(lèi)型蜡塌,支持快速查找碉纳。右子節(jié)點(diǎn)>樹(shù)中的任意一個(gè)結(jié)點(diǎn)值>左子結(jié)點(diǎn)。極端情況下二叉查找樹(shù)可能會(huì)退化成鏈表馏艾,時(shí)間復(fù)雜度會(huì)退化到 O(n)劳曹。

平衡二叉查找樹(shù)可以解決復(fù)雜度退化問(wèn)題。
AVL樹(shù)符合平衡二叉查找樹(shù)的嚴(yán)格定義琅摩,即任何節(jié)點(diǎn)的左右子樹(shù)高度相差不超過(guò) 1铁孵,但AVL樹(shù)維持平衡的成本很高。
紅黑樹(shù)是近似平衡房资,是一種不嚴(yán)格的平衡二叉查找樹(shù)蜕劝,在維護(hù)平衡的成本相對(duì)較低。在工程中更喜歡用紅黑樹(shù)而不是平衡二叉樹(shù)。紅黑樹(shù)實(shí)現(xiàn)復(fù)雜熙宇,可以用跳表替代鳖擒。

是完全二叉樹(shù),堆的重要應(yīng)用有:優(yōu)先級(jí)隊(duì)列烫止、求 Top K 和求中位數(shù)蒋荚。

②Trie樹(shù)

主要應(yīng)用于多模式串匹配(在一個(gè)串中同時(shí)查找多個(gè)串),如搜索引擎馆蠕。
擴(kuò)展:AC自動(dòng)機(jī)

(6)圖

圖的存儲(chǔ)方式有鄰接矩陣鄰接表期升。鄰接矩陣存儲(chǔ)比較浪費(fèi)空間,特別是存儲(chǔ)是稀疏圖(頂點(diǎn)多互躬,邊少)播赁,但查詢(xún)效率高,而且方便矩陣運(yùn)算(如弗洛伊德算法)吼渡。鄰接表的存儲(chǔ)方式比較節(jié)省存儲(chǔ)空間容为,但鏈表不方便查找,可以通過(guò)跳表寺酪、紅黑樹(shù)坎背、散列表等提高查詢(xún)效率。

可以應(yīng)用于存儲(chǔ)社交網(wǎng)絡(luò)的好友關(guān)系寄雀。

圖基本的搜索算法是廣度優(yōu)先搜索算法深度優(yōu)先搜索算法得滤。

其他算法:拓?fù)渑判?/strong>

(7)散列表

①散列函數(shù)

散列函數(shù)可以算出數(shù)據(jù)存放對(duì)應(yīng)的數(shù)組下標(biāo),當(dāng)出現(xiàn)散列沖突可以通過(guò)開(kāi)放尋址法(適合數(shù)據(jù)量比較小盒犹、裝載因子小的時(shí)候)懂更、鏈表法(適合存儲(chǔ)大對(duì)象、大數(shù)據(jù)量的散列表急膀【谛可以用紅黑樹(shù)代替鏈表來(lái)優(yōu)化)來(lái)解決。
當(dāng)散列表中空閑位置不多的時(shí)候卓嫂,散列沖突的概率就會(huì)大大提高皂股。為了保證散列表的操作效率,一般情況下會(huì)保證散列表有一定比例的空閑槽位命黔。

②哈希算法

將任意長(zhǎng)度的二進(jìn)制值串映射為固定長(zhǎng)度的二進(jìn)制值串呜呐,這個(gè)映射的規(guī)則就是哈希算法,而通過(guò)原始數(shù)據(jù)映射之后得到的二進(jìn)制值串就是哈希值悍募。

哈希算法常見(jiàn)應(yīng)用

  • 安全加密(MD5蘑辑、SHA等)

  • 唯一標(biāo)識(shí)
    對(duì)大數(shù)據(jù)做信息摘要,通過(guò)一個(gè)較短的二進(jìn)制編碼來(lái)表示很大的數(shù)據(jù)坠宴。

  • 數(shù)據(jù)校驗(yàn)
    校驗(yàn)數(shù)據(jù)的完整性和正確性洋魂。如HTTPS中通過(guò)摘要算法保證數(shù)據(jù)的完整性

  • 散列函數(shù)
    散列函數(shù)中用到的散列算法更加看重的是散列的平均性和哈希算法的執(zhí)行效率

  • 負(fù)載均衡
    通過(guò)哈希算法,對(duì)客戶(hù)端 IP 地址或者會(huì)話 ID 計(jì)算哈希值,將取得的哈希值與服務(wù)器列表的大小進(jìn)行取模運(yùn)算副砍,最終得到應(yīng)該被路由到的服務(wù)器編號(hào)衔肢。
    這樣就可以把同一個(gè) IP 過(guò)來(lái)的所有請(qǐng)求,都路由到同一個(gè)后端服務(wù)器上豁翎,實(shí)現(xiàn)會(huì)話粘滯(session sticky)角骤。

  • 數(shù)據(jù)分片
    通過(guò)哈希算法對(duì)數(shù)據(jù)分片,以實(shí)現(xiàn)采用多機(jī)分布式處理海量數(shù)據(jù)

  • 分布式存儲(chǔ)
    針對(duì)海量數(shù)據(jù)的緩存心剥,可以通過(guò)哈希算法對(duì)數(shù)據(jù)取哈希值邦尊,然后對(duì)機(jī)器個(gè)數(shù)取模,得到應(yīng)該存儲(chǔ)的緩存機(jī)器編號(hào)优烧。
    這種方法有個(gè)缺點(diǎn)就是當(dāng)擴(kuò)容或縮容蝉揍,所有的數(shù)據(jù)都要重新計(jì)算哈希值,然后重新搬移到正確的機(jī)器上畦娄。相當(dāng)于緩存中的數(shù)據(jù)都失效了又沾,可能發(fā)生雪崩效應(yīng),壓垮數(shù)據(jù)庫(kù)熙卡≌人ⅲ可以采用一致性哈希算法來(lái)解決。

③散列表和二叉查找樹(shù)比較
  • 散列表插入再膳、刪除挺勿、查找的時(shí)間復(fù)雜度是O(1)曲横,而二叉查找樹(shù)在比較平衡的基礎(chǔ)上才能做到O(logN)喂柒。
  • 但是散列表的數(shù)據(jù)是無(wú)序的,二叉查找樹(shù)可以通過(guò)中序遍歷在O(N)的時(shí)間復(fù)雜度內(nèi)獲得有序的數(shù)據(jù)禾嫉。
  • 散列表擴(kuò)容耗時(shí)多灾杰,遇到散列沖突時(shí),性能不穩(wěn)定熙参。平衡二叉樹(shù)性能穩(wěn)定艳吠,時(shí)間復(fù)雜度穩(wěn)定在 O(logn)。
④為什么散列表經(jīng)常和鏈表一起使用(如LinkedHashMap)孽椰?
  • 散列表數(shù)據(jù)存儲(chǔ)是無(wú)序的昭娩,無(wú)法支持按照某種順序快速地遍歷數(shù)據(jù)。如果希望按照順序遍歷散列表中的數(shù)據(jù)黍匾,需要將散列表中的數(shù)據(jù)拷貝到數(shù)組中栏渺,然后排序,再遍歷锐涯】恼铮可以通過(guò)維護(hù)一個(gè)鏈表維持順序,實(shí)現(xiàn)LRU淘汰算法。
  • 借助散列表和雙向鏈表可以實(shí)現(xiàn)O(1)的查詢(xún)霎终、刪除操作

4.排序算法

(1)非線性排序算法

算法 最好時(shí)間復(fù)雜度 最壞時(shí)間復(fù)雜度 平均時(shí)間復(fù)雜度 是否原地排序 是否穩(wěn)定 適用場(chǎng)景
冒泡排序 O(n) O(n2) O(n2) 規(guī)模數(shù)據(jù)排序
插入排序 O(n) O(n2) O(n2) 規(guī)模數(shù)據(jù)排序
選擇排序 O(n2) O(n2) O(n2) 規(guī)模數(shù)據(jù)排序
快速排序 O(nlogn) O(n2) O(nlogn) 規(guī)模數(shù)據(jù)排序
歸并排序 O(nlogn) O(nlogn) O(nlogn) 規(guī)模數(shù)據(jù)排序
堆排序 O(nlogn) O(nlogn) O(nlogn) 優(yōu)先級(jí)隊(duì)列滞磺、 Top K 、求中位數(shù)

ps:為了兼顧任意規(guī)模數(shù)據(jù)的排序莱褒,一般都會(huì)首選時(shí)間復(fù)雜度是 O(nlogn) 的排序算法來(lái)實(shí)現(xiàn)排序函數(shù)击困。

(2)線性排序算法

算法 時(shí)間復(fù)雜度 是否原地排序 是否穩(wěn)定 排序數(shù)據(jù)要求 適用場(chǎng)景
桶排序 O(n)(選擇快排) ①要排序的數(shù)據(jù)需要很容易就能劃分成 m 個(gè)桶②數(shù)據(jù)在各個(gè)桶之間的分布是比較均勻的 外部排序
計(jì)數(shù)排序 O(n+k) k是數(shù)據(jù)范圍 非負(fù)整數(shù) 數(shù)據(jù)范圍不大
基數(shù)排序 O(dn) d是維度 ①需要可以分割出獨(dú)立的“位”來(lái)比較,而且位之間有遞進(jìn)的關(guān)系 ②位之間有遞進(jìn)的關(guān)系 ③每一位的數(shù)據(jù)范圍不能太大保礼,要可以用線性排序算法來(lái)排序 數(shù)據(jù)范圍較大

ps:桶排序中時(shí)間復(fù)雜度沛励、是否原地排序、是否穩(wěn)定取決于桶內(nèi)選取的排序算法炮障;桶排序其實(shí)是一種算法思想目派;計(jì)數(shù)排序是一種特殊的桶排序

5.字符串匹配算法

(1)單模式串匹配(在一個(gè)主串中查找一個(gè)模式串)

①BF(Brute Force)算法

暴力匹配/樸素匹配算法。

思路:把主串的長(zhǎng)度記作 n胁赢,模式串的長(zhǎng)度記作 m企蹭。在主串中,檢查起始位置分別是 0智末、1谅摄、2…n-m 且長(zhǎng)度為 m 的 n-m+1 個(gè)子串,看有沒(méi)有跟模式串匹配的系馆。

時(shí)間復(fù)雜度:

最壞情況時(shí)間復(fù)雜度是 O(n*m)送漠。

適用場(chǎng)景:

適合主串和模式串都不太長(zhǎng)的情況。在實(shí)際的軟件開(kāi)發(fā)中由蘑,絕大部分情況下闽寡,樸素的字符串匹配算法就夠用了。

②RK算法

RK 算法是借助哈希算法對(duì) BF 算法進(jìn)行改造尼酿。

思路:對(duì)主串中每個(gè)子串分別求哈希值爷狈,然后拿子串的哈希值與模式串的哈希值比較,減少了比較的時(shí)間裳擎。

時(shí)間復(fù)雜度:

O(n)涎永。極端情況下,如果哈希算法存在大量的沖突鹿响,每次都要再對(duì)比子串和模式串本身羡微,那時(shí)間復(fù)雜度就會(huì)退化成 O(n*m)。

適用場(chǎng)景:

字符集范圍不要太大且模式串不要太長(zhǎng)惶我, 否則hash值可能沖突妈倔。但設(shè)計(jì)一個(gè)良好的哈希算法會(huì)比較困難。

③BM算法

借助“壞字符規(guī)則”和“好后綴規(guī)則”指孤,在每一輪比較時(shí)启涯,讓模式串盡可能多移動(dòng)幾位贬堵,減少無(wú)謂的比較。

a.壞字符規(guī)則

從模式串的末尾往前倒著匹配结洼,當(dāng)發(fā)現(xiàn)某個(gè)字符沒(méi)法匹配的時(shí)候黎做。把這個(gè)沒(méi)有匹配的字符叫作壞字符(主串中的字符)
ps:壞字符的位置越靠右松忍,下一輪模式串的挪動(dòng)跨度就可能越長(zhǎng)蒸殿,節(jié)省的比較次數(shù)也就越多。這就是BM算法從右向左檢測(cè)的好處鸣峭。

壞字符對(duì)應(yīng)的模式串中的字符下標(biāo)記作 si宏所。如果壞字符在模式串中存在,把這個(gè)壞字符在模式串中的下標(biāo)記作xi摊溶。如果不存在爬骤, xi 記作 -1。模式串往后移動(dòng)的位數(shù)就等于 si-xi莫换。如果壞字符在模式串里多處出現(xiàn)霞玄,選擇最靠后的那個(gè)作為xi 。

時(shí)間復(fù)雜度:

利用壞字符規(guī)則拉岁,BM 算法最好時(shí)間復(fù)雜度是 O(n/m)坷剧。【 n是主串長(zhǎng)度喊暖,m是模式串長(zhǎng)度 】

單純使用壞字符規(guī)則還是不夠的惫企。因?yàn)楦鶕?jù) si-xi 計(jì)算出來(lái)的移動(dòng)位數(shù),有可能是負(fù)數(shù)陵叽,比如主串是 aaaaaaaaaaaaaaaa狞尔,模式串是 baaa。不但不會(huì)向后滑動(dòng)模式串咨跌,還有可能倒退沪么。

b.好后綴規(guī)則

遇到無(wú)法匹配的壞字符后硼婿,看好后綴在模式串中锌半,是否有另一個(gè)匹配的子串。如果有寇漫,則按如下滑動(dòng):



如果沒(méi)有則從好后綴的后綴子串中刊殉,找一個(gè)最長(zhǎng)的并且能跟模式串的前綴子串匹配的。


時(shí)間復(fù)雜度:

好后綴預(yù)處理最壞時(shí)間復(fù)雜度O(m * m)州胳,匹配O(n)【m是模式串長(zhǎng)度记焊,n是主串長(zhǎng)度】

如何運(yùn)用壞字符和好后綴規(guī)則?

分別計(jì)算好后綴和壞字符往后滑動(dòng)的位數(shù)栓撞,然后取兩個(gè)數(shù)中最大的遍膜,作為模式串往后滑動(dòng)的位數(shù)碗硬。這種處理方法可以避免根據(jù)壞字符規(guī)則計(jì)算得到的往后滑動(dòng)的位數(shù)有可能是負(fù)數(shù)的情況。
好后綴規(guī)則可以獨(dú)立于壞字符規(guī)則使用瓢颅。因?yàn)閴淖址?guī)則的實(shí)現(xiàn)比較耗內(nèi)存恩尾,為了節(jié)省內(nèi)存,可以只用好后綴規(guī)則來(lái)實(shí)現(xiàn) BM 算法挽懦,但算法效率就會(huì)下降一些翰意。

適用場(chǎng)景:

壞字符規(guī)則需要占用較多的空間,適合字符集不是很大的情況信柿。
壞字符和好后綴都需要對(duì)模式串進(jìn)行預(yù)處理冀偶,所以模式串最好不要太長(zhǎng)。

④KMP算法

KMP算法與BM算法類(lèi)似渔嚷,也是讓模式串盡可能多移動(dòng)幾位进鸠,減少無(wú)謂的比較,KMP算法重點(diǎn)放在已匹配前綴上形病。

思路:在模式串和主串匹配的過(guò)程中堤如,當(dāng)遇到壞字符后,對(duì)于已經(jīng)比對(duì)過(guò)的好前綴窒朋,在好前綴的后綴子串中搀罢,查找最長(zhǎng)的那個(gè)可以跟好前綴的前綴子串匹配的。假設(shè)最長(zhǎng)的可匹配的那部分前綴子串是{v}侥猩,長(zhǎng)度是 k榔至。把模式串一次性往后滑動(dòng) j-k 位,相當(dāng)于欺劳,每次遇到壞字符的時(shí)候唧取,就把 j 更新為 k,i 不變划提,然后繼續(xù)比較枫弟。

時(shí)間復(fù)雜度:

O(m+n)(其中構(gòu)建next數(shù)組是O(m),借助next數(shù)組匹配是O(n))【m是模式串長(zhǎng)度鹏往,n是主串長(zhǎng)度】淡诗。

可結(jié)合小灰大牛這篇來(lái)食用:
漫畫(huà):什么是KMP算法?

(2)多模式串匹配(在一個(gè)主串中查找多個(gè)模式串)

①Trie 樹(shù)

Trie 樹(shù)的本質(zhì)伊履,就是利用字符串之間的公共前綴韩容,將重復(fù)的前綴合并在一起。



其中唐瀑,根節(jié)點(diǎn)不包含任何信息群凶。每個(gè)節(jié)點(diǎn)表示一個(gè)字符串中的字符,從根節(jié)點(diǎn)到紅色節(jié)點(diǎn)的一條路徑表示一個(gè)字符串(注意:紅色節(jié)點(diǎn)并不都是葉子節(jié)點(diǎn))哄辣。

時(shí)間復(fù)雜度:

構(gòu)建 Trie 樹(shù)的過(guò)程请梢,需要掃描所有的字符串赠尾,時(shí)間復(fù)雜度是 O(n)【n 表示所有字符串的長(zhǎng)度和 】。
構(gòu)建好 Trie 樹(shù)后毅弧,在其中查找字符串的時(shí)間復(fù)雜度是 O(k)【k 表示要查找的字符串的長(zhǎng)度】萍虽。

空間復(fù)雜度:

空間復(fù)雜度取決于子節(jié)點(diǎn)存儲(chǔ)大小。Trie 樹(shù)有可能很浪費(fèi)內(nèi)存形真,為了解決內(nèi)存問(wèn)題杉编,可以稍微犧牲一點(diǎn)查詢(xún)的效率,將每個(gè)節(jié)點(diǎn)中的數(shù)組換成其他數(shù)據(jù)結(jié)構(gòu)咆霜,來(lái)存儲(chǔ)一個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)指針邓馒。比如有序數(shù)組、跳表蛾坯、散列表光酣、紅黑樹(shù)等。

適用場(chǎng)景:

精確匹配查找更適合用散列表或者紅黑樹(shù)來(lái)解決脉课,Trie 樹(shù)比較適合的是查找前綴匹配的字符串救军,適合多模式串公共前綴較多的匹配,如實(shí)現(xiàn)搜索關(guān)鍵詞的提示功能倘零。

②AC 自動(dòng)機(jī)

AC 自動(dòng)機(jī)實(shí)際上就是在 Trie 樹(shù)之上唱遭,加了類(lèi)似 KMP 的 next 數(shù)組,只不過(guò)此處的 next 數(shù)組是構(gòu)建在樹(shù)上呈驶。


時(shí)間復(fù)雜度:

構(gòu)建Trie 樹(shù)的時(shí)間復(fù)雜度是 O(m * len)【 len 表示敏感詞的平均長(zhǎng)度拷泽,m 表示敏感詞的個(gè)數(shù)】。
失敗指針的構(gòu)建過(guò)程就是 O(k * len)【 k是 Trie 樹(shù)中總的節(jié)點(diǎn)個(gè)數(shù)】袖瞻。
AC 自動(dòng)機(jī)做匹配的時(shí)間復(fù)雜度O(n * len)司致,因?yàn)槊舾性~并不會(huì)很長(zhǎng),實(shí)際情況下聋迎,可能近似于 O(n)脂矫。【n是主串長(zhǎng)度】

適用場(chǎng)景:

適合大量文本中多模式串的精確匹配查找霉晕,如敏感詞過(guò)濾

6.二分查找

(1)特點(diǎn)

二分查找依賴(lài)的是順序表結(jié)構(gòu)庭再,也就是數(shù)組,并且針對(duì)的是有序數(shù)據(jù)娄昆。時(shí)間復(fù)雜度為O(logN)佩微。

(2)使用場(chǎng)景

①二分查找只能用在插入缝彬、刪除操作不頻繁萌焰,一次排序多次查找的場(chǎng)景中
②數(shù)據(jù)量太小不適合,此時(shí)使用順序查找就足夠了谷浅。數(shù)據(jù)量太大也不適合扒俯,二分查找的底層需要依賴(lài)數(shù)組這種數(shù)據(jù)結(jié)構(gòu)奶卓,而數(shù)組為了支持隨機(jī)訪問(wèn)的特性,要求內(nèi)存空間連續(xù)撼玄,對(duì)內(nèi)存的要求比較苛刻夺姑。
③如果數(shù)據(jù)之間的比較操作非常耗時(shí),不管數(shù)據(jù)量大小掌猛,推薦使用二分查找盏浙。比如對(duì)于大字符串間的比較,可以盡量減少比較次數(shù)

7.其他算法思想

(1)貪心算法

貪心算法實(shí)際上是動(dòng)態(tài)規(guī)劃算法的一種特殊情況荔茬。針對(duì)一組數(shù)據(jù)废膘,定義了限制值和期望值,希望從中選出幾個(gè)數(shù)據(jù)慕蔚,在滿(mǎn)足限制值的情況下丐黄,期望值最大。

適用場(chǎng)景:

指導(dǎo)設(shè)計(jì)基礎(chǔ)算法孔飒。比如Prim 和 Kruskal 最小生成樹(shù)算法 灌闺、Dijkstra 單源最短路徑算法、霍夫曼編碼(Huffman Coding)(一種十分有效的編碼方法坏瞄,廣泛用于數(shù)據(jù)壓縮中)桂对。

(2)分治算法

分治算法(divide and conquer)的核心思想是分而治之 ,也就是將原問(wèn)題劃分成 n 個(gè)規(guī)模較小鸠匀,并且結(jié)構(gòu)與原問(wèn)題相似的子問(wèn)題接校,遞歸地解決這些子問(wèn)題,然后再合并其結(jié)果狮崩,就得到原問(wèn)題的解蛛勉。

分治算法一般都比較適合用遞歸來(lái)實(shí)現(xiàn)。

適用場(chǎng)景:

用來(lái)指導(dǎo)編碼睦柴,降低問(wèn)題求解的時(shí)間復(fù)雜度(如歸并排序求逆序?qū)Γ?br> 解決海量數(shù)據(jù)處理問(wèn)題诽凌。比如 MapReduce 本質(zhì)上就是利用了分治思想。

(3)回溯算法

回溯相當(dāng)于窮舉搜索坦敌。窮舉所有的解侣诵,找到滿(mǎn)足期望的解。通過(guò)把問(wèn)題求解的過(guò)程分為多個(gè)階段狱窘。每個(gè)階段杜顺,我們都會(huì)面對(duì)一個(gè)岔路口,我們先隨意選一條路走蘸炸,當(dāng)發(fā)現(xiàn)這條路走不通的時(shí)候(不符合期望的解)躬络,就回退到上一個(gè)岔路口,另選一種走法繼續(xù)走搭儒。
時(shí)間復(fù)雜度非常高穷当,是指數(shù)級(jí)別的提茁。

適用場(chǎng)景:

用來(lái)解決廣義的搜索問(wèn)題:從一組可能的解中,選擇出一個(gè)滿(mǎn)足要求的解馁菜。(如八皇后茴扁、0-1背包問(wèn)題、正則表達(dá)式匹配等)
時(shí)間復(fù)雜度高汪疮,只能用來(lái)解決小規(guī)模數(shù)據(jù)的問(wèn)題峭火。
適合用遞歸來(lái)實(shí)現(xiàn),在實(shí)現(xiàn)的過(guò)程中智嚷,剪枝操作是提高回溯效率的一種技巧躲胳。利用剪枝,我們并不需要窮舉搜索所有的情況纤勒,從而提高搜索效率坯苹。

(4)動(dòng)態(tài)規(guī)劃

把問(wèn)題分解為多個(gè)階段,每個(gè)階段對(duì)應(yīng)一個(gè)決策摇天。我們記錄每一個(gè)階段可達(dá)的狀態(tài)集合(去掉重復(fù)的)粹湃,然后通過(guò)當(dāng)前階段的狀態(tài)集合,來(lái)推導(dǎo)下一個(gè)階段的狀態(tài)集合泉坐,動(dòng)態(tài)地往前推進(jìn)为鳄。
動(dòng)態(tài)規(guī)劃是一種空間換時(shí)間的算法思想。執(zhí)行效率較回溯高腕让,但是空間復(fù)雜度也高孤钦。

能解決的問(wèn)題

符合一個(gè)模型,三個(gè)特征的問(wèn)題纯丸。

  • 一個(gè)模型
    多階段決策最優(yōu)解模型偏形。解決問(wèn)題的過(guò)程,需要經(jīng)歷多個(gè)決策階段觉鼻。每個(gè)決策階段都對(duì)應(yīng)著一組狀態(tài)俊扭。然后我們尋找一組決策序列,經(jīng)過(guò)這組決策序列坠陈,能夠產(chǎn)生最終期望求解的最優(yōu)值萨惑。
  • 三個(gè)特征
    最優(yōu)子結(jié)構(gòu):可以通過(guò)子問(wèn)題的最優(yōu)解,推導(dǎo)出問(wèn)題的最優(yōu)解仇矾。后面階段的狀態(tài)可以通過(guò)前面階段的狀態(tài)推導(dǎo)出來(lái)庸蔼。
    無(wú)后效性:在推導(dǎo)后面階段的狀態(tài)的時(shí)候,只關(guān)心前面階段的狀態(tài)值贮匕,不關(guān)心這個(gè)狀態(tài)是怎么一步一步推導(dǎo)出來(lái)的姐仅;某階段狀態(tài)一旦確定,就不受之后階段的決策影響。
    重復(fù)子問(wèn)題:不同的決策序列萍嬉,到達(dá)某個(gè)相同的階段時(shí)乌昔,可能會(huì)產(chǎn)生重復(fù)的狀態(tài)
解題思路
  • 狀態(tài)轉(zhuǎn)移表法:回溯算法實(shí)現(xiàn) - 定義狀態(tài) - 畫(huà)遞歸樹(shù) - 找重復(fù)子問(wèn)題 - 畫(huà)狀態(tài)轉(zhuǎn)移表 - 根據(jù)遞推關(guān)系填表 - 將填表過(guò)程翻譯成代碼
  • 狀態(tài)轉(zhuǎn)移方程法:找最優(yōu)子結(jié)構(gòu) - 寫(xiě)狀態(tài)轉(zhuǎn)移方程 - 將狀態(tài)轉(zhuǎn)移方程翻譯成代碼
適用場(chǎng)景:

用來(lái)求解最優(yōu)問(wèn)題隙疚,比如求最大值壤追、最小值等等。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末供屉,一起剝皮案震驚了整個(gè)濱河市行冰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌伶丐,老刑警劉巖悼做,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異哗魂,居然都是意外死亡肛走,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)责循,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)钧栖,“玉大人诈豌,你說(shuō)我怎么就攤上這事『校” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵崔列,是天一觀的道長(zhǎng)梢褐。 經(jīng)常有香客問(wèn)我,道長(zhǎng)赵讯,這世上最難降的妖魔是什么盈咳? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮边翼,結(jié)果婚禮上猪贪,老公的妹妹穿的比我還像新娘。我一直安慰自己讯私,他們只是感情好热押,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著斤寇,像睡著了一般桶癣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上娘锁,一...
    開(kāi)封第一講書(shū)人閱讀 51,245評(píng)論 1 299
  • 那天牙寞,我揣著相機(jī)與錄音,去河邊找鬼。 笑死间雀,一個(gè)胖子當(dāng)著我的面吹牛悔详,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惹挟,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼茄螃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了连锯?” 一聲冷哼從身側(cè)響起归苍,我...
    開(kāi)封第一講書(shū)人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎运怖,沒(méi)想到半個(gè)月后拼弃,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摇展,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年吻氧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咏连。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡盯孙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捻勉,到底是詐尸還是另有隱情镀梭,我是刑警寧澤,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布踱启,位于F島的核電站报账,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏埠偿。R本人自食惡果不足惜透罢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冠蒋。 院中可真熱鬧羽圃,春花似錦、人聲如沸抖剿。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)斩郎。三九已至脑融,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缩宜,已是汗流浹背肘迎。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工甥温, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人妓布。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓姻蚓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親匣沼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子狰挡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容