给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 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]
-
初始化:创建哑节点
dummy和当前节点指针cur,初始化进位carry为0。 -
循环处理:使用
while循环遍历l1和l2,直到两者都为空且无进位。 -
计算和与进位:在循环中,计算当前位的和
sum,包括进位和当前节点的值。更新进位carry为sum / 10。 -
创建新节点:为新节点分配内存,设置值为
sum % 10,并将当前节点的next指向新节点,然后移动当前节点指针。 -
返回结果:循环结束后,返回哑节点的
next,即结果链表的头节点,并释放哑节点的内存。
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
// 创建哑节点
struct ListNode* dummy = malloc(sizeof(struct ListNode));
dummy->val = 0;
dummy->next = NULL;
struct ListNode* cur = dummy; // 当前节点指针
int carry = 0; // 进位
// 循环直到l1、l2都为空且进位为0
while (l1 != NULL || l2 != NULL || carry != 0) {
int sum = carry; // 初始化为进位值
if (l1 != NULL) {
sum += l1->val;
l1 = l1->next;
}
if (l2 != NULL) {
sum += l2->val;
l2 = l2->next;
}
carry = sum / 10; // 计算新的进位
// 创建新节点
struct ListNode* newNode = malloc(sizeof(struct ListNode));
newNode->val = sum % 10;
newNode->next = NULL;
cur->next = newNode; // 将新节点连接到当前节点后面
cur = cur->next; // 移动当前节点
}
struct ListNode* result = dummy->next; // 结果链表的头节点
free(dummy); // 释放哑节点
return result;
}
疑难点:
进位和取余
carry = sum / 10; // 计算新的进位
newNode->val = sum % 10;
什么是进位?
在十进制加法中:
-
当两个数字相加的结果 ≥10 时,会产生进位
-
进位值 = 和 ÷ 10 的整数部分
-
当前位保留的值 = 和 % 10
示例说明
以题目中的示例为例:
-
链表1: 2 → 4 → 3 (表示数字342)
-
链表2: 5 → 6 → 4 (表示数字465)
计算过程:
-
个位:2 + 5 = 7 → 无进位,结果为7
-
十位:4 + 6 = 10 → 进位1,结果为0
-
百位:3 + 4 + 进位1 = 8 → 无进位,结果为8
-
最终结果:7 → 0 → 8 (表示数字807)
什么是取余?
-
当我们计算两个数字相加时,结果可能超过9(即超过单个数字能表示的范围)
-
我们需要将这个结果分解为两部分:
-
当前位的值:结果的个位数(通过
sum % 10获取) -
进位值:结果的十位数(通过
sum / 10获取)
-
具体示例
-
简单情况(无进位):
-
如果
sum = 7(例如 2+5) -
7 % 10 = 7→ 当前位值为7 -
7 / 10 = 0→ 进位为0
-
-
需要进位的情况:
-
如果
sum = 14(例如 6+8) -
14 % 10 = 4→ 当前位值为4 -
14 / 10 = 1→ 进位为1
-

3372

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



