[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 已收录到公众号,欢迎关注 :)
[Leetcode题解]2. 两数相加-链表遍历和重构的更多相关文章
- LeetCode | No.2 两数相加
题目描述 给出两个非空的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序的方式存储的,并且它们的每个节点只能存储一位数字.如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和 ...
- LeetCode :2.两数相加 解题报告及算法优化思路
题目连接:2.两数相加 题意 题目难度标为 中等, 因为题意上有一部分理解难度,以及需要数据结构的链表基础. 还不知道到链表的童鞋可以粗略的看下百度百科或者是翻出数据结构的书看一看,通俗一点的语言来解 ...
- LeetCode刷题--两数相加(中等)
题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...
- LeetCode Golang 2. 两数相加
2. 两数相加 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链 ...
- 两数相加[链表加法] LeetCode.2
给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和 ...
- Leetcode:2. 两数相加
题目描述: 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来 ...
- leetCode刷题 | 两数相加
给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和 ...
- LeetCode练习2 两数相加
问题如下: 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来 ...
- 【LeetCode】2. 两数相加
题目 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表 ...
随机推荐
- spring boot 在框架中注入properties文件里的值(Spring三)
前一篇博客实现了打开第一个页面 链接:https://blog.csdn.net/qq_38175040/article/details/105709758 本篇博客实现在框架中注入propertie ...
- python函数小案例
python函数 目录 python函数 1.写一个函数求三个数的和,并返回结果 2.写一个函数,求平均值,并返回结果 写一个函数,求每个数与平均值之间的差,并放回结果 1.写一个函数求三个数的和,并 ...
- Docker实战(1):通过配置文件启动MongoDB
系统环境:Centos7 MongoDB 4.0.0 创建文件 注意:创建文件全是为了Docker run做准备,文件所对应的路径需与下一步的映射路径所对应,路径可自我更改. mkdir mongo ...
- Orchard Core创建CMS/Blog站点
安装.NET Core SDK 下载并安装当前最新版本.NET Core SDK 3.1: https://dotnet.microsoft.com/download 安装visual studio ...
- cnpm install 报错
报错如图所示,请观下文 1,npm cache clean --force 2,进入文件,rm -rf node_modules/ ---- 暴力直接
- Spark Extracting,transforming,selecting features
Spark(3) - Extracting, transforming, selecting features 官方文档链接:https://spark.apache.org/docs/2.2.0/m ...
- jdk在linux下安装、配置环境变量
1.jdk下载: 下载地址:https://www.oracle.com/java/technologies/javase-downloads.html 2. 3. 4.解压jdk到/usr/loca ...
- 注解在Spring中的运用(对象获取、对象单例/多例、值的注入、初始化/销毁方法、获取容器)
1.注解的方式获取对象 (1)导包: (2)书写配置文件(要保证已经导入了约束): <?xml version="1.0" encoding="UTF-8" ...
- Git-使用Rebase合并分支
commit 合并 在开发过程中,可能会出现多个 commit 所涉及的逻辑都是同一个功能模块,此时,会导致 log tree 非常的混乱,不美观,因此,我们可以将多个 commit 进行合并,变成一 ...
- c#RSA的SHA1加密与AES加密、解密
前言:公司项目对接了一个对数据保密性要求较高的java公司.api接口逻辑是这样的:他们提供 SHA1私钥 与 AES的秘钥.我们需要将 传递查询参数 通过SHA1 私钥加密再转换成 十六进制 字符串 ...