演算法練習week7 leetcode23

2021-08-30 02:29:34 字數 1503 閱讀 2422

題目大意:

給出若干已經排好序鍊錶的頭節點指標,將它們合併成乙個成序的鍊錶,返回其頭結點指標。

示例:給定鍊錶:1->2->3 和 4->6->8,則應當返回鍊錶 1->2->3->4->6->8的頭節點指標。

解題思路:

一開始看到這道題,我覺得會比較複雜。因為要排成有序鍊錶需要先逐個比較,再將節點插入對應的位置。後來聯想到之前使用過的雜湊表,變換思路如下:遍歷每乙個鍊錶,將每個節點的值插入到容器set中,同時建立乙個雜湊表,儲存節點的值和它出現的次數。所有鍊錶遍歷結束之後,所有出現過的節點值都儲存到了set中,並且按順序排好。此時,只需要再遍歷一遍set,再找到雜湊表中對應出現的次數,就可完成合併鍊錶的建立。實現**如下: 

以上**在本地通過了測試,但上傳到leetcode時,卻出現了編譯錯誤。似乎是因為它不允許在類外建立全域性變數。回過頭看題目,我發現有乙個重要條件完全沒有派上用場:給出的鍊錶是已經排好序的,這說明演算法複雜度肯定不是最優的。並且,實現**中,我自行建立了集合、對映表,又新建了節點,導致演算法的空間複雜度也會很大,進一步降低了其實用性。 

在discuss中,高票的c++解答是基於之前的兩鍊錶合併問題的拓展。ac**如下:

/**

1. definition for singly-linked list.

2. struct listnode

6. };

*/class solution

return lists.front();

}listnode* merge2lists(listnode* l1, listnode* l2)

else}};

可以看出,它在時間和空間複雜度上都更加優越。經仔細分析,在合併兩個鍊錶時,它是通過遞迴的方式尋找當前節點的下一節點,直到有一條鍊錶為空為止。 

對我來說,遞迴一直是乙個理解上的難點。因此我試著從幾個例子中去理解它的意思。以鍊錶1:1->2->3和鏈:2:2->3->4為例: 

1. 首先需要尋找合成鍊錶的頭結點,換言之,兩個煉表頭結點中值較小的那乙個,即1。 

2. 隨後尋找下一節點。此時,需要比較當前節點在本鍊錶中的下一節點與另一鍊錶的當前節點值的大小,較小者為下一節點。此處,為2和2,不妨取鍊錶2中的「2」作為下一節點。 

3. 再次尋找下一節點,與步驟2類似,比較2與3,鍊錶1中的「2」成為下一節點 

…… 4. 重複以上過程,當需要確定鍊錶1中的3的下一節點時,發現它在本鍊錶中已經是最後乙個節點。因此另一煉表中的節點自動成為下一節點。由於兩個鍊錶本身是成序的,因此也無需進行下一步的搜尋,即可得到結果。 

如此,只需要用乙個函式merge2lists即可實現上述過程。不難發現,如果採用順序的思維,是很容易理解以上的**的。但輪到自己去實現時,仍然很難完成。歸根結底,是因為習慣了先程式中得到結果,再將結果進行進一步的處理的方式,不習慣遞迴的思維方法——先進行處理,再將結果逐步回帶。

leetcode演算法練習7 單詞拆分

解析 給定乙個非空字串 s 和乙個包含非空單詞列表的字典 worddict,判定 s 是否可以被空格拆分為乙個或多個在字典 現的單詞。拆分時可以重複使用字典中的單詞。你可以假設字典中沒有重複的單詞。輸入 s leetcode worddict leet code 輸出 true 解釋 返回 true...

week 7 A Floyd演算法解決傳遞閉包問題

眾所周知,tt 有乙隻魔法貓。這一天,tt 正在專心致志地玩 貓和老鼠 遊戲,然而比賽還沒開始,聰明的魔法貓便告訴了 tt 比賽的最終結果。tt 非常詫異,不僅詫異於他的小貓咪居然會說話,更詫異於這可愛的小不點為何有如此魔力?魔法貓告訴 tt,它其實擁有一張遊戲勝負表,上面有 n 個人以及 m 個勝...

Week7 TT的旅行日記 最短路演算法

題目描述 眾所周知,tt 有乙隻魔法貓。今天他在 b 站上開啟了一次旅行直播,記錄他與魔法貓在喵星旅遊時的奇遇。tt 從家裡出發,準備乘坐貓貓快線前往喵星機場。貓貓快線分為經濟線和商業線兩種,它們的速度與價錢都不同。當然啦,商業線要比經濟線貴,tt 平常只能坐經濟線,但是今天 tt 的魔法貓變出了一...