一、题目描述
给定两个用链表表示的整数,每个节点包含一个数位。
这些数位是反向存放的,也就是个位排在链表首部。
编写函数对这两个整数求和,并用链表形式返回结果。
示例:
输入:(7 -> 1 -> 6) + (5 -> 9 -> 2),即617 + 295
输出:2 -> 1 -> 9,即912
输入:(1) + (9 -> 9),即1+99
输出:0 -> 0 -> 1,即100
二、题解
思路:因为链表是按照个位十位百位逆序存储的,所以直接顺序遍历链表,第一个就是个位,接着十位,百位等。两个链表的值相加存储作为一个新节点存储,进位信息单独存到一个变量中,每次都加上这个进位信息。
遍历操作使用两个指针遍历:
- 一个指针(head)指向一开始的头节点(保存链表)
- 一个指针(last)指向上一次的节点(依次往后移动)
进位及存储的元素判断:
- 判断是否有进位:
两个节点的和/10
如果是0则没有进位,如果是1则有进位。 - 如果相加是超过了10(即存在进位信息),那么存储在当前节点的值就是余数:
两个节点的和%10
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//进位标志
int carry = 0;
//开头的节点
ListNode head = null;
//指向上一个节点
ListNode last = null;
while (l1 != null || l2 != null){
int val = (l1 == null ? 0 : l1.val) + (l2 == null ? 0 : l2.val);
//该位置上的数
int cur = val + carry;
Integer remainder = null;
if ((cur / 10) > 0) {
//有进位 余数
remainder = cur % 10;
}
//求和之后的新节点
ListNode newNode = new ListNode(remainder != null ? remainder : cur);
if (head == null) {
//一开始的头节点
head = newNode;
} else {
last.next = newNode;
}
last = newNode;
//存储进位信息 给下一次相加使用
carry = cur / 10;
l1 = (l1 == null ? null : l1.next);
l2 = (l2 == null ? null : l2.next);
}
//循环结束了如果carry还有值,说明最后还进了一位,再增加一个节点
if (carry == 1) {
last.next = new ListNode(carry, null);
}
return head;
}
}