一、题目
给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字0之外,这两个数都不会以0开头。
二、示例
示例 1:
【输入】l1 = [2,4,3], l2 = [5,6,4]
【输出】[7,0,8]
【解释】342 + 465 = 807
示例 2:
【输入】l1 = [0], l2 = [0]
【输出】[0]
示例 3:
【输入】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
- 题目数据保证列表表示的数字不含前导零
ListNode的结构:
它是一个单向链表,由next引用下一个节点。
三、解题思路
看完这道题,第一个想法就是,按位进行相加操作,并将结果保存新的节点中,即:new ListNode(l1.val + l2.val)
。那么如果相加的总和大于9的话,则需要执行进位操作,我们这里使用int carryBit来保存进位值(默认为0
,进位则被赋值为1
)。所以,新节点的创建其实应该是new ListNode(l1.val + l2.val + carryBit)。如下图所示:
这里面有一个小的优化点,就是在于如果两个链表长度不一样,短链表遍历完毕后,我们是如何处理长链表剩余未遍历的部分的。这里面有两种情况,如果carryBit等于1,即:需要进位,那么就还是按照进位操作的方式计算并创建新的节点。但是,如果不需要进位,即:carryBit等于0,那么我们其实可以直接将剩余部分的链表“拼接”到新的链表中。如下图所示,我们只需要将Node(8).next=Node(2)
即可,免去了遍历的操作。
四、代码实现
class SolutionOf2 {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode headNode = null;
ListNode temp = null;
int carryBit = 0;
while (true) {
// 有一个或者两个都是末尾节点,并且没有进位,则跳出循环
if ((l1 == null || l2 == null) && carryBit == 0) {
temp.next = (l1 != null) ? l1 : l2;
break;
}
// 判断两个节点相加后,是否需要进位
int sum;
if ((sum = (l1 != null ? l1.val : 0) + (l2 != null ? l2.val : 0) + carryBit) > 9) {
sum -= 10;
carryBit = 1;
} else {
carryBit = 0;
}
ListNode sumNode = new ListNode(sum);
if (headNode == null) {
headNode = sumNode;
} else {
temp.next = sumNode;
}
temp = sumNode;
l1 = l1 != null ? l1.next : null;
l2 = l2 != null ? l2.next : null;
}
return headNode;
}
}
今天的文章内容就这些了,最后一句话:
写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的点赞&分享。
更多技术干货,欢迎大家关注公众号“爪哇缪斯”(^o^)/~ 「干货分享,每周更新」
好文推荐
题目来源:力扣(LeetCode)