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 已收录到公众号,欢迎关注 :)

[Leetcode题解]2. 两数相加-链表遍历和重构的更多相关文章

  1. LeetCode | No.2 两数相加

    ​题目描述 给出两个非空的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序的方式存储的,并且它们的每个节点只能存储一位数字.如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和 ...

  2. LeetCode :2.两数相加 解题报告及算法优化思路

    题目连接:2.两数相加 题意 题目难度标为 中等, 因为题意上有一部分理解难度,以及需要数据结构的链表基础. 还不知道到链表的童鞋可以粗略的看下百度百科或者是翻出数据结构的书看一看,通俗一点的语言来解 ...

  3. LeetCode刷题--两数相加(中等)

    题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...

  4. LeetCode Golang 2. 两数相加

    2. 两数相加 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链 ...

  5. 两数相加[链表加法] LeetCode.2

    给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和 ...

  6. Leetcode:2. 两数相加

    题目描述: 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来 ...

  7. leetCode刷题 | 两数相加

    给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和 ...

  8. LeetCode练习2 两数相加

    问题如下: 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来 ...

  9. 【LeetCode】2. 两数相加

    题目 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字.   如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...

随机推荐

  1. 单应用模式 - Layuiadmin单页版放入TP6.0的部署方案

    thinkphp6.0.3单应用模式.layuiadmin1.4.0单页版,不需要tp的视图驱动 1. 复制 src.start 两个文件夹 2. 粘贴到 thinkphp 的 public 目录下 ...

  2. python格式化输出当前时间

    import time def get_now_time(): now_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.tim ...

  3. python中faker模块:产生随机数据的模块

    #pip install faker #产生各种随机数据的模块 想要运用更多的随机数据,可以百度查找下

  4. zepto | 用事件委托去解决无法给新增添的DOM添加事件的问题

    前段时间在做一个任务的时候,碰见了一个问题:zepto无法用on事件去监听新增加的dom事件.这个问题用live可解决, 但是live在ios下失效,为了解决这个问题,我采用了暴力的方法去解决,每次添 ...

  5. Node.js 从零开发 web server博客项目[koa2重构博客项目]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  6. java基础之序列化

    转载自https://www.cnblogs.com/szlbm/p/5504166.html Java对象表示方式1:序列化.反序列化和transient关键字的作用   平时我们在Java内存中的 ...

  7. java.lang.NoSuchMethodError: org.springframework.util.Assert.isTrue(ZLjava/util/function/Supplier;)V

    spring-data-redis 2的版本只支持spring5和spring boot2+,建议降低spring-data-redis版本 <!-- redis --> <depe ...

  8. 使用VSCode和CMake构建跨平台的C/C++开发环境

    日前在学习制作LearnOpenGL教程的实战项目Breakout游戏时,希望能将这个小游戏开发成跨平台的,支持在多个平台运行.工欲善其事必先利其器,首先需要做的自然是搭建一个舒服的跨平台C/C++开 ...

  9. Helm部署和体验jenkins

    如何快速且简单的部署 通过helm可以快速且简单的部署多种应用,关于helm的安装和使用请参考 环境信息 本次实战的环境信息如下: kubernetes集群:三台CentOS7.7服务器 kubern ...

  10. idea模拟前端向后台请求数据输出响应结果

    tools-httpClient-Test restful web service 通过上述步骤之后出现如下图 1 表示通过哪种方式请求:2 请求数据的地址头部:3 请求数据的除了头部之后的地址:4, ...