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. 在 Windows 上安装 Composer

    a.去官网 getcomposer.org 下载安装程序 b.运行安装程序,需要开启三个扩展 openssl.curl.mbstring,没有开启的话 composer 也可以帮助开启:会自动将com ...

  2. redis设置密码和查询密码

    编辑redis.windows.conf配置来启用认证. 1.初始化Redis密码: 在配置文件中有个参数: requirepass  这个就是配置redis访问密码的参数: 比如 requirepa ...

  3. SpringBoot写后端接口,看这一篇就够了!

    摘要:本文演示如何构建起一个优秀的后端接口体系,体系构建好了自然就有了规范,同时再构建新的后端接口也会十分轻松. 一个后端接口大致分为四个部分组成:接口地址(url).接口请求方式(get.post等 ...

  4. [程序员代码面试指南]最长递增子序列(二分,DP)

    题目 例:arr=[2,1,5,3,6,4,8,9,7] ,最长递增子序列为1,3,4,8,9 题解 step1:找最长连续子序列长度 dp[]存以arr[i]结尾的情况下,arr[0..i]中的最长 ...

  5. Linux实战(12):Centos装机常用脚本-进阶版

    #!/bin/bash #shell菜单演示 function menu() { echo -e `date` cat <<EOF ---------------------------- ...

  6. Prometheus-Alertmanager告警对接到企业微信

    之前写过将Prometheus的监控告警信息通过Alertmanager推送到钉钉群. 最近转移了阵地,需要将Prometheus监控告警信息推送到企业微信群,经过两天的摸索,以及查了网上的一些资料, ...

  7. dubbo学习(十一)dubbo知识点总结

    一.基础概念 Dubbo是个啥? 定义:Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC 分布式远程调用服务框架,现已成为 Apache 基金会孵化项目. 核心功能:远程服务调用. 为什么要 ...

  8. 论文阅读笔记: Natural Language Inference over Interaction Space

    这篇文章提出了DIIN(DENSELY INTERACTIVE INFERENCE NETWORK)模型. 是解决NLI(NATURAL LANGUAGE INFERENCE)问题的很好的一种方法. ...

  9. 有没有异常处理翻车过的,绩效还被打了C

    絮叨 因为程序异常处理问题,就在前几天龙叔的服务挂了几秒钟. 完了,马上季度末打绩效,竟然在这里翻车了,心如刀绞啊. 虽然没有影响到用户体验,但是找到问题并解决掉问题是工程师日常追求之一. 作为一个优 ...

  10. MySQL: 2、SQL语言

    一.SQL的简介: 1.SQL的概念: SQL就是结构化查询语言,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询.更新和管理关系数据库系统 2.SQL的作用:   - ...