题目
- 两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 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]
来源:力扣热题100 2. 两数相加
思路(注意事项)
代码精简将三个while
和一个if
合并,使得代码精简很多。
代码精简
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* head = new ListNode(0); // 虚拟头节点
ListNode* p = head; // 当前节点指针
int flag = 0; // 进位标志
// 遍历两个链表
while (l1 != nullptr || l2 != nullptr || flag != 0) {
int sum = flag; // 初始化为进位值
if (l1 != nullptr) {
sum += l1->val;
l1 = l1->next;
}
if (l2 != nullptr) {
sum += l2->val;
l2 = l2->next;
}
flag = sum >= 10 ? 1 : 0; // 更新进位标志
sum %= 10; // 取个位数
p->next = new ListNode(sum); // 创建新节点并连接到链表
p = p->next; // 移动当前节点指针
}
return head->next; // 返回结果链表的头节点
}
};
纯代码
class Solution {
private:
void func (int sum)
{
flag = sum >= 10 ? 1 : 0;
sum %= 10;
ListNode* l = new ListNode(sum);
p -> next = l;
p = p ->next;
}
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* head = new ListNode(0);
ListNode *p = head;
int flag = 0;
while (l1 != nullptr && l2 != nullptr)
{
int sum = l1 -> val + l2 -> val + flag;
func(sum);
l1 = l1 -> next;
l2 = l2 -> next;
}
while (l1 != nullptr)
{
int sum = l1 -> val + flag;
func(sum);
l1 = l1 -> next;
}
while (l2 != nullptr)
{
int sum = l2 -> val + flag;
func(sum);
l2 = l2 -> next;
}
if (flag == 1)
{
ListNode* l = new ListNode(1);
p -> next = l;
}
return head -> next;
}
};
题解(加注释)
class Solution {
private:
int flag = 0; // 进位标志,初始化为 0
ListNode* p = nullptr; // 当前节点指针,用于构建新链表
// 辅助函数:处理当前位的和,并更新链表
void func(int sum) {
flag = sum >= 10 ? 1 : 0; // 判断是否需要进位
sum %= 10; // 取个位数
ListNode* l = new ListNode(sum); // 创建新节点
p->next = l; // 将新节点连接到链表
p = p->next; // 移动当前节点指针
}
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* head = new ListNode(0); // 创建虚拟头节点
p = head; // 初始化当前节点指针
// 遍历两个链表,逐位相加
while (l1 != nullptr && l2 != nullptr) {
int sum = l1->val + l2->val + flag; // 计算当前位的和(包括进位)
func(sum); // 处理当前位的和
l1 = l1->next; // 移动 l1 指针
l2 = l2->next; // 移动 l2 指针
}
// 处理 l1 剩余的节点
while (l1 != nullptr) {
int sum = l1->val + flag; // 计算当前位的和(包括进位)
func(sum); // 处理当前位的和
l1 = l1->next; // 移动 l1 指针
}
// 处理 l2 剩余的节点
while (l2 != nullptr) {
int sum = l2->val + flag; // 计算当前位的和(包括进位)
func(sum); // 处理当前位的和
l2 = l2->next; // 移动 l2 指针
}
// 如果最后还有进位,添加一个新节点
if (flag == 1) {
ListNode* l = new ListNode(1);
p->next = l;
}
return head->next; // 返回结果链表的头节点(跳过虚拟头节点)
}
};