题目链接:2. 两数相加 - 力扣(LeetCode)
解题思路
步骤1:理解问题
首先,我们需要理解链表是如何表示数字的。在这个问题中,链表的每个节点存储一个数字的一位,且最低位在链表的头部。例如,链表 [2,4,3]
表示数字 342
。
步骤2:遍历链表
我们需要同时遍历两个链表,从每个链表的头部开始,对应节点的值相加。这就像我们手写加法一样,从最低位开始相加。
步骤3:处理进位
在加法中,如果两个数字相加超过了9,就会产生进位。在链表中,如果两个节点的值相加大于9,我们就需要将进位记录下来,并将其加到下一对节点的和中。
步骤4:创建新链表
在遍历的过程中,我们创建一个新的链表来存储结果。每个节点的值是两个链表对应节点值的和(可能还要加上进位)。
步骤5:处理剩余进位
在遍历完两个链表后,如果还有进位,我们需要在结果链表的头部添加一个新的节点来存储这个进位。
详细步骤
-
初始化:创建一个虚拟的头节点
preHead
,用于辅助构建结果链表。同时,初始化一个变量carry
来存储进位,初始值为0。 -
遍历链表:同时遍历两个链表,直到两个链表都遍历完。在每一步中:
- 取出两个链表的当前节点的值,如果某个链表已经遍历完,就取0作为该链表的当前节点的值。
- 计算当前位的和:
sum = val1 + val2 + carry
,其中val1
和val2
分别是两个链表当前节点的值。 - 更新进位:
carry = sum / 10
。 - 创建一个新的节点,其值为
sum % 10
(即当前位的和减去进位后的结果),并将其链接到preHead
后面。
-
处理剩余进位:如果遍历完两个链表后,
carry
仍然不为0,说明还有一个进位需要处理。创建一个新的节点,其值为carry
,并将其链接到结果链表的头部。 -
返回结果:由于我们使用了虚拟头节点
preHead
,所以返回结果链表时,应该返回preHead.next
。
代码实现
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int carry = 0;//进位
ListNode result = new ListNode();//最终结果
ListNode cur = result; // 当前结果链表的位置
while(l1 != null || l2 != null){// 当两者都不为null时循环结束
// l1 与 l2 不为null时,其值与进位相加
int value = (l1 != null ? l1.val : 0) + (l2 != null ? l2.val : 0) + carry;
ListNode temp = new ListNode(value % 10);// 通过对10取余,取个位数
cur.next = temp;// 更新next
carry = value / 10;// 更新进位值
// 链表后移
cur = cur.next;
l1 = l1 != null ? l1.next : null;
l2 = l2 != null ? l2.next : null;
}
// 处理最后的进位
if(carry != 0){
ListNode temp = new ListNode(carry);
cur.next = temp;
}
//注意这里返回的是result.next,相当于result多了一个虚拟头节点
return result.next;
}
}