zoukankan      html  css  js  c++  java
  • [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 已收录到公众号,欢迎关注 :)

  • 相关阅读:
    zen_cart 支付提前生成订单
    SSL加密过程
    建立自己的代码库
    自动代码工具
    mssqlserver 学习资源
    自己动手写操作系统(1)
    Windows Phone 7 优秀开源项目收集
    正则表达式工具
    .net framework source code
    vs2012 打包应用程序(创建部署/安装包)
  • 原文地址:https://www.cnblogs.com/QuLory/p/13837796.html
Copyright © 2011-2022 走看看