一、问题剖析:两数相加究竟是什么?
在数据结构场景下,两数相加通常指两个非空链表分别表示两个非负整数。链表中的每个节点只存储一位数字,且按逆序方式排列。任务是将这两个数相加,并以相同逆序的链表形式返回和。
例如:链表 1 为 2 -> 4 -> 3(代表 342),链表 2 为 5 -> 6 -> 4(代表 465)。相加结果为 807,对应返回链表应为 7 -> 0 -> 8。
采用逆序存储是为了方便从最低位(个位)开始进行加法操作,模拟手工计算过程,便于处理进位。
二、实现思路:一步步拆解问题
-
初始化相关变量 创建一个新的链表存储结果,使用虚拟头节点(哨兵节点)简化操作。定义指针指向当前新链表末尾,以及记录进位值的变量(初始为 0)。
-
遍历两个链表进行相加 同时遍历两个输入链表,获取当前节点值。若某链表已遍历结束,其当前节点值视为 0。将两值与进位值相加得到总和。
-
计算当前位数字和新的进位值 当前位数字为总和对 10 取余,新进位值为总和除以 10 取整。
-
添加新节点到结果链表 创建新节点存储当前位数字,添加到结果链表末尾,移动末尾指针。C++ 中需使用
new动态分配内存。 -
处理链表遍历结束后的进位 若遍历结束后进位值不为 0,需在结果链表末尾新增节点存储该进位值。
-
返回结果链表 返回虚拟头节点的下一个节点作为结果链表的第一个有效节点。
三、代码实现:用 C++ 语言实战
#include <iostream>
using namespace std;
// 链表节点定义
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) {}
};
// 核心函数:两数相加
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
// 虚拟头节点
ListNode* dummy = new ();
ListNode* cur = dummy;
carry = ;
(l1 != || l2 != || carry != ) {
num1 = (l1 != ) ? l1->val : ;
num2 = (l2 != ) ? l2->val : ;
sum = num1 + num2 + carry;
carry = sum / ;
curVal = sum % ;
cur->next = (curVal);
cur = cur->next;
(l1 != ) l1 = l1->next;
(l2 != ) l2 = l2->next;
}
ListNode* result = dummy->next;
dummy;
result;
}
{
(head != ) {
cout << head->val;
(head->next != ) cout << ;
head = head->next;
}
cout << endl;
}
{
ListNode* l1 = ();
l1->next = ();
l1->next->next = ();
ListNode* l2 = ();
l2->next = ();
l2->next->next = ();
ListNode* res = (l1, l2);
cout << ;
(res);
l1->next->next; l1->next; l1;
l2->next->next; l2->next; l2;
res->next->next; res->next; res;
;
}

