题目:

  给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字0之外,这两个数都不会以0开头。

示例:

  输入:l1 = [2,4,3], l2 = [5,6,4]
  输出:[7,0,8]
  解释:342 + 465 = 807

  输入:l1 = [0], l2 = [0]
  输出:[0]

  输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
  输出:[8,9,9,9,0,0,0,1]

提示:

  • 每个链表中的节点数在范围 [1, 100] 内
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零

思路:模拟

  由于输入的两个链表都是逆序存储数字的位数的,因此两个链表中同一位置的数字可以直接相加。我们可以同时遍历两个链表,计算他们的和。本题没有太大的难度,但是有几种不同的操作顺序,选择不同的顺序,代码编写难度会不同,效率也会有细微差别。

  新建链表结点or利用已有结点,显然利用已有结点构造链表在时间上快于新建结点,但编写难度比新建结点复杂。一边遍历一边处理数据or构造完链表再处理数据,显然第一种时间更快(只需一次遍历),同样编写代码稍复杂。

  我更偏向于运行效率,所以我利用l1结点建立链表newl,将计算结果记录在l1.val中,将进位值加到下一结点,处理直到某一链表遍历完成,此时会出现三种情况。(1)l1.next == null && l2.next != null(2)l1.next != null && l2.next == null(3)l1.next == null && l2.next == null。只有第一种情况会导致无法利用l1结点构造链表,需要特殊处理,也很容易实现,将l1.next = l2.next,就将剩余全部结点链接到newl中,接着遍历进行处理,最后一个结点需单独处理,因为如果最后一结点值大于10,则需要进位,就需要新建一结点保存进位值,最后将新建结点加入newl即完成。

// Java代码
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode newl = l1;// 利用l1构造和链表
while (l1.next != null && l2.next != null) {// 处理都不为空的正常情况
l1.val += l2.val;// 将l1和l2的值的和保存在l1
if (l1.val >= 10) {// 进行/和%操作处理
l1.next.val += l1.val / 10;// 将进位加到l1.next
l1.val %= 10;// 更新当前结点值
} l1 = l1.next;// 指针后移
l2 = l2.next;// 指针后移
}
if (l2.next != null) {
// 处理l2.next == null的特殊情况,另外两种情况不需要处理
// 即l1.next和l2.next都为空;以及l1.next == null
l1.next = l2.next;
} l1.val += l2.val;// 将l1和l2的值的和保存在l1
while (l1.next != null) {// 遍历剩下的结点
if (l1.val >= 10) {// 进行/和%操作处理
l1.next.val += l1.val / 10;// 将进位加到l1.next
l1.val %= 10;// 更新当前结点值
}
l1 = l1.next;// 指针后移
} if (l1.val >= 10) {// 处理最后一个结点的特殊情况
// 后边已无结点,需新建
ListNode newnode = new ListNode(l1.val / 10, null);
l1.next = newnode;// 将新结点加入链表
l1.val %= 10;// 更新当前结点值
} return newl;// 返回最终的和链表
}
}
// C++代码
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* newl = l1;// 利用l1构造和链表
while (l1->next != nullptr && l2->next != nullptr) {// 处理都不为空的正常情况
l1->val += l2->val;// 将l1和l2的值的和保存在l1
if (l1->val >= 10) {// 进行/和%操作进行处理
l1->next->val += l1->val / 10;// 将进位加到l1.next
l1->val %= 10;// 更新当前结点值
} l1 = l1->next;// 指针后移
l2 = l2->next;// 指针后移
}
if (l2->next != nullptr) {
// 处理l2.next == null的特殊情况,另外两种情况不需要处理
// 即l1.next和l2.next都为空;以及l1.next == null
l1->next = l2->next;
} l1->val += l2->val;// 将l1和l2的值的和保存在l1
while (l1->next != nullptr) {// 遍历剩下的结点
if (l1->val >= 10) {// 进行/和%操作进行处理
l1->next->val += l1->val / 10;// 将进位加到l1.next
l1->val %= 10;// 更新当前结点值
}
l1 = l1->next;// 指针后移
} if (l1->val >= 10) {// 处理最后一个结点的特殊情况
// 后边已无结点,需新建
ListNode* newnode = new ListNode(l1->val / 10, nullptr);
l1->next = newnode;// 将新结点加入链表
l1->val %= 10;// 更新当前结点值
} return newl;// 返回最终的和链表
}
};

[LeetCode]2. 两数相加(难度:中等)的更多相关文章

  1. LeetCode 445——两数相加 II

    1. 题目 2. 解答 2.1 方法一 在 LeetCode 206--反转链表 和 LeetCode 2--两数相加 的基础上,先对两个链表进行反转,然后求出和后再进行反转即可. /** * Def ...

  2. Leetcode 002. 两数相加

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

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

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

  4. LeetCode 445. 两数相加 II(Add Two Numbers II)

    445. 两数相加 II 445. Add Two Numbers II 题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个 ...

  5. Leetcode 445. 两数相加 II

    1.题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. ...

  6. LeetCode 2. 两数相加(Add Two Numbers)

    2. 两数相加 2. Add Two Numbers 题目描述 You are given two non-empty linked lists representing two non-negati ...

  7. LeetCode 2——两数相加(JAVA)

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

  8. Java实现 LeetCode 2 两数相加

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

  9. leetcode TOP100 两数相加

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

随机推荐

  1. Chrome & console.log & color & js

    Chrome & console.log & color & js console.log & color // OK log(`%cchat_list =\n%c${ ...

  2. H5 直播 & App 直播

    H5 直播 & App 直播 polyv 直播 https://github.com/polyv 宝利威 直播 https://www.polyv.net/live/ SDK https:// ...

  3. 大送福利!市场香饽饽VAST到底什么来头,为何被高价估值

    近日,NGK星空计划新币VAST成为了香饽饽,还未正式上线前,市场讨论的热度就居高不下.如今NGK推出1万VAST免费送新人福利更是将这波热度推向了高潮. 具体福利规则:在美国加州时间2021年2月8 ...

  4. NGK算力市场,不止有动静态收益还有SPC空投!

    随着数字货币交易的火热,云算力挖矿也悄然崛起.越来越多的用户开启云算力挖矿,以获取更多的收益.相较于传统的矿机挖矿,用户通过购买算力进行云挖矿,节省了购买矿机以及维护的成本.另一方面,也降低了安全风险 ...

  5. PAUL ADAMS ARCHITECT:爱丁堡的房屋价值创历史新高

    近日,英国知名房产公司保罗·亚当斯公司根据一组调查报告表示,今年第三季度,爱丁堡的房价再创历史新高,并向大家分析了原因. 保罗·亚当斯公司(公司编号:07635831)是英国一家著名的房地产公司,总部 ...

  6. transient的作用及序列化

    1.transient 介绍 Java中的transient关键字,transient是短暂的意思.对于transient 修饰的成员变量,在类的实例对象的序列化处理过程中会被忽略. 因此,trans ...

  7. SQL Server中DELETE和TRUNCATE的区别

    ​DELETE和TRUNCATE语句之间的区别是求职面试中最常见的问题之一.这两条语句都可以从表中删除数据.然而,也有不同之处. 本文将重点讨论这些差异,并通过实例加以说明. TRUNCATE DEL ...

  8. close() 和fluse()区别

    1.close()默认包含了一次flush()操作,关闭之后,就不能再写入了. 2.flush()刷新,flush()之后,可以接着写入. 3.缓冲区默认大小是8192字节,如果小于8192字节,不会 ...

  9. 解决使用Redis时配置 fastjson反序列化报错 com.alibaba.fastjson.JSONException: autoType is not support

    1.问题描述 在使用redis时,配置自定义序列化redisTemplate为FastJsonRedisSerializer .  1 /** 2 * 自定义redis序列化器 3 */ 4 @Sup ...

  10. 控制流程-if/while/for

    目录 一.控制流程之if判断 1.单分支结构 2.双分支结构 3.多分支结构 二.控制流程之while循环 1.基本使用 2.break 3.continue 三.流程控制之for循环 1.break ...