Golang從合併連結串列聊遞迴
從合併連結串列聊遞迴
遞迴是工程師最常見的一種解決問題的方式,但是有時候不容易真正掌握。有人說是看起來很簡單,自己寫起來會費點勁。
最著名的例子就是斐波那契數列(Fibonacci sequence),透過尋找遞推公式來計算出結果。
而最近刷到的一道合併連結串列的演算法題,也可以使用遞迴來實現。下面看看題目描述吧:
將兩個升序連結串列合併為一個新的 升序 連結串列並返回。新連結串列是透過拼接給定的兩個連結串列的所有節點組成的。 示例: 輸入:1->2->4, 1->3->4輸出:1->1->2->3->4->4來源:力扣(LeetCode)
先丟擲本人觀點,遞迴的關鍵是:找到 邊界條件和 遞迴公式。
分析一下題目,可以發現用第一個連結串列l1的頭部節點來去和l2的節點對比,如果大於l2的當前節點,那麼偏移l1的next和l2繼續對比大小。反之如果l1的頭節點對比L2的當前節點更小,那麼就需要對l2做類似處理。
這種不斷對比和偏移的過程,可以總結出一種遞迴公式。
用虛擬碼寫法就是:
if l1.val < l2.val: l1.next = mergeTwoList(l1.next, l2) return l1else: l2.next = mergeTwoList(l1, l2.next) return l2
而邊界條件就是在不斷偏移的時候,走到某個連結串列的最後一個節點為止,虛擬碼就是:
if l1 === null: return l2if l2 === null: return l1
用golang來實現,程式碼也很清晰:
type ListNode struct { Val int Next *ListNode }func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode { if l1 == nil { return l2 } if l2 == nil { return l1 } if l1.Val < l2.Val { l1.Next = mergeTwoLists(l1.Next, l2) return l1 } else { l2.Next = mergeTwoLists(l1, l2.Next) return l2 } }
在LeetCode裡面提交,執行反饋如下:
執行結果: 透過 顯示詳情 執行用時: 0 ms, 在所有 Go 提交中擊敗了 100.00% 的使用者 記憶體消耗: 2.6 MB, 在所有 Go 提交中擊敗了 63.64% 的使用者
可以看到遞迴是非常消耗記憶體的,它迴圈呼叫,猶如爾羅斯套娃,一層一層返回內層的呼叫結果。
如果要最佳化的話可以使用迭代方式來實現,程式碼需要做一些調整:
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode { head := &ListNode{} result := head for l1 != nil && l2 != nil { if l1.Val < l2.Val { head.Next = l1 head = head.Next l1 = l1.Next } else { head.Next = l2 head = head.Next l2 = l2.Next } } if l1 == nil { head.Next = l2 } if l2 == nil { head.Next = l1 } return result.Next }
可以看出需要建立一個頭部指標來做偏移,而最終result作為一個合成結果連結串列來儲存結果。
最後提交執行,發現結果資料稍微好看了一丟丟:
執行用時: 4 ms, 在所有 Go 提交中擊敗了 62.28% 的使用者 記憶體消耗: 2.5 MB, 在所有 Go 提交中擊敗了 100.00% 的使用者
由於在資料量不大的情況下,其實效能差距也不大,所以使用遞迴也是沒有毛病的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69959503/viewspace-2722467/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 利用遞迴實現連結串列的排序(歸併排序)遞迴排序
- 反轉連結串列、合併連結串列、樹的子結構
- 連結串列面試題(七)---合併兩個有序連結串列面試題
- 合併K個排序連結串列排序
- 資料結構與演算法——歸併排序: 陣列&連結串列&遞迴&非遞迴解法全家桶資料結構演算法排序陣列遞迴
- 連結串列-迴圈連結串列
- 【資料結構】遞迴實現連結串列逆序資料結構遞迴
- 連結串列4: 迴圈連結串列
- C++單連結串列遞迴遍歷操作C++遞迴
- 單連結串列逆置遞迴演算法遞迴演算法
- 反轉連結串列系列題練習遞迴遞迴
- 演算法基礎~連結串列~排序連結串列的合併(k條)演算法排序
- [Golang]力扣LeetBook—初級演算法—連結串列—迴文連結串列(快慢指標)Golang力扣演算法指標
- leetcode:21. 合併兩個有序連結串列(連結串列,簡單)LeetCode
- 連結串列合併-排序-logo列印參考排序Go
- 連結串列以及golang介入式連結串列的實現Golang
- leecode.23. 合併K個升序連結串列
- 23. 合併K個元素的有序連結串列
- 演算法搜狗筆試題連結串列合併演算法筆試
- 連結串列歸併排序排序
- 教你如何運用python/golang實現迴圈連結串列PythonGolang
- 實現反轉連結串列--遞迴、迭代、雙指標、棧遞迴指標
- 淺談歸併排序:合併 K 個升序連結串列的歸併解法排序
- [程式設計題]從尾到頭列印連結串列 牛客網練習 java遞迴程式設計Java遞迴
- leetcode23. 合併K個排序連結串列LeetCode排序
- LeetCode 23. 合併K個排序連結串列LeetCode排序
- 單向迴圈連結串列
- 詳細分析連結串列中的遞迴性質(Java 實現)遞迴Java
- 遞迴演算法-不帶頭節點的單連結串列遞迴演算法
- golang 實現連結串列爽不爽?Golang
- 【演算法-java實現】合併兩個有序連結串列演算法Java
- leetcode雙週賽(2)-合併兩個連結串列LeetCode
- JZ-016-合併兩個排序的連結串列排序
- 每日leetcode——21. 合併兩個有序連結串列LeetCode
- 劍指offer面試17 合併兩個排序的連結串列面試排序
- 連結串列反轉非遞迴演算法!看不懂打死我!遞迴演算法
- 單鏈迴圈連結串列(初版
- 複習下C 連結串列操作(雙向迴圈連結串列,查詢迴圈節點)