0 题目描述
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
题目链接:2. 两数相加
1 算法思想
这里以示例1为例,因为链表中存储的每一个数字都是逆序的,所以首尾就是存储的最低位。因此要求两个链表所表示的数之和并逆序存储,步骤如下:
- 首先分别遍历两链表对应位置上的元素,并求和
- 得到新节点的值,因为节点值范围不超过10,所以若是两数和大于10还需要向前进位
- 新建节点并插入到保存结果的链表中
- 终止条件是当两个链表都遍历完了
注意:这里存在一个问题就是进位的问题,若果是遍历到两个链表的最后一位需要进位怎么办?
可以用一个全局变量保存上一次的进位,每使用一次进位就将该变量置为0,链表遍历之后再判断进位变量是否为0,如果不为0说明最后一位还存在进位,那么就需要再初始化一个值为该变量的新节点并插入到结果链表的末尾。
2 代码实现
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode newNode = new ListNode(-1); //结果链表的头结点
ListNode pred = newNode; //用于保存新插入链表节点的上一个位置,便于找到当前的链表尾
ListNode cur1 = l1; //l1链表的移动指针
ListNode cur2 = l2; //l2链表的移动指针
int temp = 0; //存储两数之和的进位
while (cur1 != null || cur2 != null){
int num1=0,num2=0;
if (cur1 != null) num1 = cur1.val;
if (cur2 != null) num2 = cur2.val;
int sum = num1+num2;
if (temp > 0){ //判断是否存在进位
sum += temp; //加上进位
temp = 0; //置零
}
if (sum >= 10){ //大于10 下一个节点需要进位
temp = sum / 10;
sum = sum % 10;
}
ListNode node = new ListNode(sum);
pred.next = node; //新节点插入到结果链表尾
pred = node; //保存节点位置
//移动指针
if (cur1 != null) cur1 = cur1.next;
if (cur2 != null) cur2 = cur2.next;
}
//判断最后是否还要进位,考虑最高位需要进位的情况
if (temp != 0){
pred.next = new ListNode(temp);
}
return newNode.next;
}
3 测试结果