[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 已收录到公众号,欢迎关注 :)
作者:逸云沙鸥
出处:http://www.cnblogs.com/QuLory/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。