题目来源
题目描述
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 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
- 题目数据保证列表表示的数字不含前导零
题目解析
本题我的解题思路是:
首先:判断出 l1 和 l2 两个链表哪个长,我们以较长的链表作为基础,即将较短的链表合并入较长的链表中,避免创建新链表。
比较两个链表长短的策略:
- 首先:定义两个指针 ll1 和 ll2 分别指向 l1 和 l2。
- 然后:ll1 和 ll2 同步next移动,直到一方为 null 时停止。
- 最后:检查 ll1 和 ll2 谁为 null,谁就较短。
为了代码简单,我们可以总是保证 l1 是较长链表(如果 l1 是较短的,则互换 l1 和 l2)。
之后:就是同步遍历 l1 和 l2,将 l2 对应位值 加入 l1 对应位值中
- 由于 l1 是较长的,因此同步遍历过程中,l2 可能变为 null,因此我们需要注意判空,即当 l2 为 null 时,l1 对应位值 += 0。
- 合并后,检查 l1 每位的值,若对应值 >= 10,则需要进位,以及取余。
C源码实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *addTwoNumbers(struct ListNode *l1, struct ListNode *l2) {
// 比较两个链表的长度
struct ListNode *ll1 = l1;
struct ListNode *ll2 = l2;
// 同步遍历
while (ll1 != NULL && ll2 != NULL) {
ll1 = ll1->next;
ll2 = ll2->next;
}
// 如果ll1先遍历完,则l1更短,为了代码简单,我们这里保证l1总是指向较长的链表
if (ll1 == NULL) {
struct ListNode *tmp = l1;
l1 = l2;
l2 = tmp;
}
// l3记录结果
struct ListNode *l3 = l1;
// 逐位相加
while (l1 != NULL) {
// 将较短链表对应位值 合并入 较长链表对应位值 中
l1->val += (l2 != NULL ? l2->val : 0);
// 进位、取余
if (l1->val >= 10) {
if (l1->next == NULL) {
l1->next = malloc(sizeof(struct ListNode));
l1->next->val = 0;
l1->next->next = NULL;
}
l1->next->val += l1->val / 10; // 进位
l1->val %= 10; // 取余
}
// 继续遍历
l1 = l1->next;
if (l2 != NULL) {
l2 = l2->next;
}
}
return l3;
}
C++源码实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
// 比较两个链表的长度
ListNode* ll1 = l1;
ListNode* ll2 = l2;
// 同步遍历
while (ll1 != nullptr && ll2 != nullptr) {
ll1 = ll1->next;
ll2 = ll2->next;
}
// 如果ll1先遍历完,则l1更短,为了代码简单,我们这里保证l1总是指向较长的链表
if (ll1 == nullptr) {
ListNode* tmp = l1;
l1 = l2;
l2 = tmp;
}
// l3记录结果
ListNode* l3 = l1;
// 逐位相加
while (l1 != nullptr) {
// 将较短链表对应位值 合并入 较长链表对应位值 中
l1->val += l2 != nullptr ? l2->val : 0;
// 进位、取余
if (l1->val >= 10) {
if (l1->next == nullptr) {
l1->next = new ListNode(0);
}
l1->next->val += l1->val / 10; // 进位
l1->val %= 10; // 取余
}
// 继续遍历
l1 = l1->next;
if (l2 != nullptr) {
l2 = l2->next;
}
}
return l3;
}
};
Java源码实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
// 比较两个链表的长度
ListNode ll1 = l1;
ListNode ll2 = l2;
// 同步遍历
while (ll1 != null && ll2 != null) {
ll1 = ll1.next;
ll2 = ll2.next;
}
// 如果ll1先遍历完,则l1更短,为了代码简单,我们这里保证l1总是指向较长的链表
if (ll1 == null) {
ListNode tmp = l1;
l1 = l2;
l2 = tmp;
}
// l3记录结果
ListNode l3 = l1;
// 逐位相加
while (l1 != null) {
// 将较短链表对应位值 合并入 较长链表对应位值 中
l1.val += (l2 != null ? l2.val : 0);
// 进位、取余
if (l1.val >= 10) {
if (l1.next == null)
l1.next = new ListNode(0);
l1.next.val += l1.val / 10; // 进位
l1.val %= 10; // 取余
}
// 继续遍历
l1 = l1.next;
if (l2 != null) {
l2 = l2.next;
}
}
return l3;
}
}
Python源码实现
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
# 比较两个链表的长度
ll1 = l1
ll2 = l2
# 同步遍历
while ll1 and ll2:
ll1 = ll1.next
ll2 = ll2.next
# 如果ll1先遍历完,则l1更短,为了代码简单,我们这里保证l1总是指向较长的链表
if ll1 is None:
l1, l2 = l2, l1
# l3记录结果
l3 = l1
# 逐位相加
while l1:
# 将较短链表对应位值 合并入 较长链表对应位值 中
l1.val += (l2.val if l2 else 0)
# 进位、取余
if l1.val >= 10:
if l1.next is None:
l1.next = ListNode(0)
l1.next.val += l1.val // 10 # 进位
l1.val %= 10 # 取余
# 继续遍历
l1 = l1.next
if l2:
l2 = l2.next
return l3
JavaScript源码实现
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var addTwoNumbers = function (l1, l2) {
// 比较两个链表的长度
let ll1 = l1;
let ll2 = l2;
// 同步遍历
while (ll1 != null && ll2 != null) {
ll1 = ll1.next;
ll2 = ll2.next;
}
// 如果ll1先遍历完,则l1更短,为了代码简单,我们这里保证l1总是指向较长的链表
if (ll1 == null) {
const tmp = l1;
l1 = l2;
l2 = tmp;
}
// l3记录结果
const l3 = l1;
// 逐位相加
while (l1 != null) {
// 将较短链表对应位值 合并入 较长链表对应位值 中
l1.val += l2 != null ? l2.val : 0;
// 进位、取余
if (l1.val >= 10) {
if (l1.next == null) l1.next = new ListNode(0);
l1.next.val += parseInt(l1.val / 10); // 进位
l1.val %= 10; // 取余
}
// 继续遍历
l1 = l1.next;
if (l2 != null) l2 = l2.next;
}
return l3;
};
244

被折叠的 条评论
为什么被折叠?



