链表——两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
这道题是链表经典题,核心就是模拟竖式加法:从低位加到高位,处理进位,刚好和题目里链表逆序存数字完美匹配。
题目理解:
- 两个链表:逆序存数字,比如数字342存为 2->4->3
- 每位都是0~9
- 你要把它们相加,结果也逆序存成链表返回
- 必须处理进位(9+9=18,存8,进1)
解题思路:
- 用虚拟头节点,不用处理空链表
- 双指针遍历两个链表
- 每一位计算:当前和 = l1值 + l2值 + 进位
- 新节点存:和%10
- 新进位:和/10
- 链表走完后,进位不为0要多加一个节点
- 返回虚拟头节点的下一个节点
完整代码运行如下:
#include
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) {}
};
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
// 虚拟头节点(你刚学会的知识点!)
ListNode* dummy = new ListNode(-1);
ListNode* cur = dummy;
int carry = 0; // 进位
// 只要有一个链表没走完,或还有进位,就继续
while (l1 != nullptr || l2 != nullptr || carry != 0) {
// 取当前位的值,为空则取0
int val1 = (l1 != nullptr) ? l1->val : 0;
int val2 = (l2 != nullptr) ? l2->val : 0;
// 当前位总和 = 数1 + 数2 + 进位
int sum = val1 + val2 + carry;
// 新节点存 个位
cur->next = new ListNode(sum % 10);
// 新进位存 十位
carry = sum / 10;
// 指针后移
cur = cur->next;
if (l1 != nullptr) l1 = l1->next;
if (l2 != nullptr) l2 = l2->next;
}
// 返回真正的结果链表
return dummy->next;
}
};
// ===================== 测试代码 =====================
void printList(ListNode* head) {
while (head) {
cout << head->val << " ";
head = head->next;
}
cout << endl;
}
int main() {
// 构建 l1: 2 -> 4 -> 3
ListNode* l1 = new ListNode(2);
l1->next = new ListNode(4);
l1->next->next = new ListNode(3);
// 构建 l2: 5 -> 6 -> 4
ListNode* l2 = new ListNode(5);
l2->next = new ListNode(6);
l2->next->next = new ListNode(4);
Solution sol;
ListNode* res = sol.addTwoNumbers(l1, l2);
// 输出:7 0 8
printList(res);
return 0;
}
代码关键点解释:
1.虚拟头节点
- 不用判断链表是否为空
- 直接 cur->next = 新节点,超级安全
2.进位 carry
- 初始是 0
- 每次计算 sum = a + b + carry
- 当前位存 sum % 10
- 进位更新为 sum / 10
3.循环条件
while (l1 || l2 || carry)
- 两个链表可能长度不一样
- 最后可能还有进位(如 999 + 999 = 1998)
总结
- 这道题 = 链表遍历 + 竖式加法 + 进位处理
- 用虚拟头节点避免空指针特判
- 循环条件要包含进位
- 时间复杂度 O(max(n,m)),只遍历最长的链表
- 空间复杂度 O(max(n,m)),存储结果
浙公网安备 33010602011771号