问题重述
给定两个非空的链表,表示两个非负整数。链表中每个节点存储一个数字,且数字是逆序存储的(即链表的第一个节点是个位数,第二个节点是十位数,依此类推)。要求将这两个数相加,并返回一个同样以逆序方式存储的和的链表。
示例
输入:
l1 = [2, 4, 3](表示342)l2 = [5, 6, 4](表示465)
输出:
[7, 0, 8](因为342 + 465 = 807,逆序存储为7 -> 0 -> 8)
解决思路
初始化:
- 创建一个虚拟头节点(dummy),简化链表操作。
- 初始化
current指针指向dummy。 - 初始化进位
carry为0。
遍历链表:
- 同时遍历
l1和l2,直到两个链表都遍历完且进位carry为0。 - 每次取出当前节点的值(如果链表已遍历完,则取
0)。 - 计算
sum = val1 + val2 + carry。 - 更新
carry = Math.floor(sum / 10)。 - 创建新节点,值为
sum % 10,并链接到current.next。 - 移动
current到新节点。 - 移动
l1和l2(如果存在)。
- 同时遍历
处理剩余的进位:
- 如果遍历完链表后
carry > 0,则额外添加一个节点。
- 如果遍历完链表后
返回结果:
dummy.next就是新链表的头节点。
JavaScript 实现
1 | function ListNode(val, next) { |
测试示例
1 | // 示例测试 |
复杂度分析
- 时间复杂度:
O(max(n, m)),其中n和m分别是l1和l2的长度。 - 空间复杂度:
O(max(n, m)),新链表的长度最多为max(n, m) + 1(如果最后有进位)。
总结
- 使用虚拟头节点简化链表操作。
- 逐位相加,并处理进位。
- **遍历直到两个链表都结束且进位为
0**。 - 返回
dummy.next作为结果链表的头节点。