[Leetcode題解]2. 兩數相加-鏈表遍歷和重構

1. 審題leetcode 02 add-two-numbers​

我們先看一下題目,如下  :

鏈表的從前往後爲數字的低位到高位,模擬加法手算過程,從前往後遍歷即可, 注意每個數字0-9,進位要處理好;


 

2. 解體思路

主要分4步來完成,增加一個頭節點來處理後續的添加過程可能簡單些;

  • 處理l1 和 l2 共有元素的累加, 注意進位inc的累加;
  • 處理多餘的l1的內容;
  • 處理多餘的l2的內容;
  • 處理最後剩餘的進位;

 

3. 詳細代碼

3.1 直觀的循環代碼

 1 /**
 2  * Definition for singly-linked list.
 3  * type ListNode struct {
 4  *     Val int
 5  *     Next *ListNode
 6  * }
 7  */
 8  
 9 func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
10     var inc int
11     head := ListNode{0, nil}
12     lastNode := &head
13     for ; l1 != nil && l2 != nil; l1, l2 = l1.Next, l2.Next {
14         sum := l1.Val + l2.Val + inc
15         if sum >= 10 {
16             inc = 1
17             sum -= 10
18         } else {
19             inc = 0
20         }
21         temp := ListNode{sum, nil}
22         lastNode.Next = &temp
23         lastNode = &temp
24     }
25     for ; l1 != nil; l1 = l1.Next {
26         sum := l1.Val + inc
27         if sum >= 10 {
28             inc = 1
29             sum -= 10
30         } else {
31             inc = 0
32         }
33         temp := ListNode{sum, nil}
34         lastNode.Next = &temp
35         lastNode = &temp
36     }
37     for ; l2 != nil; l2 = l2.Next {
38         sum := l2.Val + inc
39         if sum >= 10 {
40             inc = 1
41             sum -= 10
42         } else {
43             inc = 0
44         }
45         temp := ListNode{sum, nil}
46         lastNode.Next = &temp
47         lastNode = &temp
48     }
49     if inc != 0 {
50         temp := ListNode{inc, nil}
51         lastNode.Next = &temp
52         lastNode = &temp
53     }
54     return head.Next
55 }

 

3.2 函數提煉重構

每個計算過程都包含取出兩個數字,和進位一起求和,處理大於10的數字,繼續下一輪;故抽取關鍵函數完成這個節點的處理

 1 func addSumNode(n1 int, n2 int, inc int, lastNode *ListNode) (int, *ListNode) {
 2     sum := n1 + n2 + inc
 3     if sum >= 10 {
 4         inc = 1
 5         sum -= 10
 6     } else {
 7         inc = 0
 8     }
 9     temp := ListNode{sum, nil}
10     lastNode.Next = &temp
11     lastNode = &temp
12     return inc, lastNode
13 }
14 
15 func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
16     var inc int
17     head := ListNode{0, nil}
18     lastNode := &head
19     for ; l1 != nil && l2 != nil; l1, l2 = l1.Next, l2.Next {
20         inc, lastNode = addSumNode(l1.Val, l2.Val, inc, lastNode)
21     }
22     for ; l1 != nil; l1 = l1.Next {
23         inc, lastNode = addSumNode(l1.Val, 0, inc, lastNode)
24     }
25     for ; l2 != nil; l2 = l2.Next {
26         inc, lastNode = addSumNode(0, l2.Val, inc, lastNode)
27     }
28     if inc != 0 {
29         inc, lastNode = addSumNode(0, 0, inc, lastNode)
30     }
31     return head.Next
32 }

 

 


 

4. 感悟總結

要重構代碼不是特別難做的事情, 看到兩次以上的重複就要有所警覺, 嘗試提取公共部分,或者進一步優化代碼整體結構, 你會發現代碼是越來越容易懂,後續添加新需求也實現其來更加容易,更好複用,所以, 重構無小事, 重構也“不是難做的大事”,因爲重構也就在點滴中; 小步快跑纔是重構的精髓;

重構後代碼看起來清爽很多, 55LOC => 32 LOC

運行時間對比:

執行用時:16 ms, 在所有 Go 提交中擊敗了39.76% 的用戶
內存消耗:4.9 MB, 在所有 Go 提交中擊敗了21.00% 的用戶

# 重構後
執行用時:12 ms, 在所有 Go 提交中擊敗了72.62% 的用戶
內存消耗:4.9 MB, 在所有 Go 提交中擊敗了26.81% 的用戶

 

永久地址: https://mp.weixin.qq.com/s/5OZx7i-oOGvDbxCWHPxi5A 已收錄到公衆號,歡迎關注 :)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章