力扣hot100:两数相加(模拟竖式加法详解)(2)
题目描述
解题思路
核心思想是模拟竖式加法,逐位相加并处理进位。具体步骤如下:
- 初始化:
- 创建虚拟头节点
result
(值为 0),简化链表操作。 - 用指针
temp
遍历结果链表,jinwei
记录进位(初始为 0)。
- 创建虚拟头节点
- 遍历链表:
- 同时遍历
l1
和l2
,若链表已结束则用0
补齐。 - 计算当前位的和:
x1 + x2 + jinwei
。
- 同时遍历
- 处理进位:
- 更新进位:
jinwei = sum / 10
。 - 当前位的值:
sum % 10
。
- 更新进位:
- 构建新节点:
- 将计算出的值存入新节点,并移动
temp
。
- 将计算出的值存入新节点,并移动
- 处理剩余进位:
- 若遍历结束仍有进位(
jinwei > 0
),需额外添加节点。
- 若遍历结束仍有进位(
关键点:
- 哑节点的使用:避免处理头节点的特殊情况。
- 进位处理:进位可能持续传递(如
999 + 1 = 1000
)。- 链表长度不一:通过补
0
解决长短链表对齐问题。
代码实现
class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode result = new ListNode(0); // 虚拟头节点ListNode temp = result; // 遍历指针int jinwei = 0; // 进位while (l1 != null || l2 != null) { // 遍历直到两链表结束// 获取当前节点的值(链表结束则补0)int x1 = (l1 != null) ? l1.val : 0;int x2 = (l2 != null) ? l2.val : 0;int sum = x1 + x2 + jinwei; // 当前位的总和jinwei = sum / 10; // 更新进位sum %= 10; // 当前位的实际值temp.next = new ListNode(sum); // 创建新节点temp = temp.next; // 移动指针// 移动原链表指针(未结束才移动)if (l1 != null) l1 = l1.next;if (l2 != null) l2 = l2.next;}// 处理最后的进位if (jinwei == 1) {temp.next = new ListNode(1);}return result.next; // 返回哑节点的下一个(真实头节点)}
}
复杂度分析
- 时间复杂度:O(max(m, n))
m
和n
分别为两链表的长度,需遍历较长链表的所有节点。 - 空间复杂度:O(max(m, n)) + 1 结果链表长度为
max(m, n)
或max(m, n) + 1
(有进位时)。
总结
本题的解题核心是模拟竖式加法,通过哑节点统一操作逻辑,重点关注:
- 进位传递:用
jinwei
记录进位,并在下一位计算中加入。 - 长短链表处理:通过条件判断
l1 != null ? l1.val : 0
补零对齐。 - 边界检查:循环结束后需检查是否有剩余进位。
此方法高效且直观,是处理链表相加问题的通用范式。掌握后,可轻松应对类似问题(如力扣 445 题“两数相加 II”)。