题目
给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
题目分析
我们小时候做的数学加减法运算(竖式)也是从最后一位算起,数字相加大于9向前进一位,按照这种方法,我们先对上面的例子做一下运算:
(这里想象一下那个熟悉的竖式)
最后一位:2 + 5 = 7 ,就将7存入新链表
倒数第二位:4 + 6 = 10 ,这时满十进一,将0存入新链表
首位:3 + 4 = 7,再加上刚才进的1,将8存入链表
这样就得到结果了
要注意有这样一种情况:当两个数字都完成了遍历,可能还剩下进位1(在两位数的加减法中,每一位上出现的最大的计算结果为:9 + 9 + 1(进位) = 19,可以看出,最大的进位的数字为1),这时新的链表就比原链表中较长的那个还长一个结点单位, 一定不能忘了最后的进位判断,否则,你小学的数学老师会揍你的
到这里还有一个要注意的问题:
上面做的是三位数加三位数的运算,那么如果两个要相加的数字不相等呢?
比如,计算一下 12 + 299 = ?
最后一位:2 + 9 = 11 ,将1存入新链表,进位为1
倒数第二位:1 + 9 + 1 = 11 ,将1存入新链表,进位为1
首位:12位数较少,百位上没有数字了,所以计算的是 进位1 + 2 = 3,将3存入链表即可
很好,发现万能的数学已经解决了这个问题,不论位数怎么相差的,都还是要从两个数字最后一位开始算起,最后位数少的先遍历完而已,再将位数多的那一位与进位做运算就好啦
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
//以上是题目给出的链表类型
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode h = new ListNode(0);//新链表头结点,放入0值
ListNode p = l1;
ListNode q = l2;
ListNode t = h;//用来跑新链表
int carry = 0;//进位,初始值为0
while (p != null || q != null) {//循环结束的条件是访问完位数较长的那个数字
int x = (p != null) ? p.val : 0;
int y = (q != null) ? q.val : 0;//x,y是两个数字某一位上要进行相加的数
int sum = carry + x + y;//某一位上的计算结果
carry = sum / 10;//下一位的进位
t.next = new ListNode(sum % 10);//将计算结果对10取余的结果存储到新链表中
t = t.next;//临时空间后移,以存储下一位计算结果
if (p != null)
p = p.next;
if (q != null)
q = q.next;//访问两个数的下一位
}
if (carry > 0)//判断计算到最后的进位是否为1
t.next = new ListNode(carry);//是则新链会多出一位
return h.next;//新链表的第一位存储的是无意义的0,于是返回它的下一位
}
}