给出两个非空
的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序
的方式存储的,而且它们的每一个节点只能存储一位
数字。java
若是,咱们将这两个数相加起来,则会返回一个新的链表来表示它们的和。bash
您能够假设除了数字0
以外,这两个数都不会以0
开头。ide
示例:3d
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 缘由:342 + 465 = 807
这个题目的意思看起来其实很简单,提供了两个链表,每一个链表表明一个非负整数,它们各自的位数是按照逆序
方式存储的,例如:(2 -> 4 -> 3)
表明整数342
,(5 -> 6 -> 4)
则表明整数465
,两数相加的结果天然是807,这就是咱们要给出的答案,可是要用链表的形式返回7 -> 0 -> 8
。题目中说明了是非空链表,因此就不用考虑链表为null的状况了。code
乍眼一看,很简单啊,不就是把两个数相加嘛,我先把它整成整数,而后相加,最后把结果整成链表,完美,哈哈哈哈,简直被本身的聪明才智给折服。blog
class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode head1 = l1; ListNode head2 = l2; int i = 0; int j = 0; int index = 0; // 将链表l1转化为整数 while (head1 != null) { i += head1.val * Math.pow(10, index); index++; head1 = head1.next; } index = 0; // 将链表l2转化为整数 while (head2 != null) { j += head2.val * Math.pow(10, index); index++; head2 = head2.next; } int sum = i + j; ListNode newHead = new ListNode(0); ListNode tmpHead = newHead; int sign = 0; // 将结果转化为链表 while (sum > 0 || sign == 0) { int tmp = sum % 10; sum = sum / 10; tmpHead.next = new ListNode(tmp); tmpHead = tmpHead.next; sign++; } return newHead.next; } }
简直轻松加愉快,让咱们来提交一下。leetcode
怎么肥四,小老弟,翻车了啊。让咱们看看错误缘由:get
输入: [9] [1,9,9,9,9,9,9,9,9,9] 输出: [0] 预期: [0,0,0,0,0,0,0,0,0,0,1]
看样子应该是整数型溢出了。。。难不倒我,改为long型不就完事了。io
class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode head1 = l1; ListNode head2 = l2; long i = 0; long j = 0; long index = 0; while (head1 != null) { i += head1.val * Math.pow(10, index); index++; head1 = head1.next; } index = 0; while (head2 != null) { j += head2.val * Math.pow(10, index); index++; head2 = head2.next; } long sum = i + j; ListNode newHead = new ListNode(0); ListNode tmpHead = newHead; int sign = 0; while (sum > 0 || sign == 0) { int tmp = (int)(sum % 10); sum = sum / 10; tmpHead.next = new ListNode(tmp); tmpHead = tmpHead.next; sign++; } return newHead.next; } }
此次总没事了吧,再提交一下:编译
这个磨人的小妖精,整出个这么大的数来折腾我,long型也溢出了。。。
逼我用绝招,是时候祭出个人BigInteger
了。
class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode head1 = l1; ListNode head2 = l2; BigInteger i = new BigInteger(0); BigInteger j = new BigInteger(0); long index = 0; while (head1 != null) { i.add(BigInteger.valueOf(head1.val * Math.pow(10, index))); index++; head1 = head1.next; } index = 0; while (head2 != null) { j.add(BigInteger.valueOf(head2.val * Math.pow(10, index))); index++; head2 = head2.next; } BigInteger sum = i.add(j); ListNode newHead = new ListNode(0); ListNode tmpHead = newHead; int sign = 0; while (sum.compareTo(0) == 1 || sign == 0) { int tmp = sum.mod(10).intValue(); sum = sum.divide(10); tmpHead.next = new ListNode(tmp); tmpHead = tmpHead.next; sign++; } return newHead.next; } }
此次,连编译都不经过了,emmmm,看来不许用BigInteger
这个类。
既然邪门歪道走不通,那就仍是用常规操做来解决吧,仔细想一想,其实也很简单,咱们从两个链表的头节点开始,一块儿遍历,将相加获得的结果存入新的链表中便可。
这里须要注意的就是要考虑进位的状况,好比:4 + 6 = 10
,那么在处理后一个节点3 + 4
的时候,须要再加1,所以须要有一个进位标志来表示是否须要进位。
另外,两个链表的长度并不必定相等,须要考虑像上面那样一个很长,一个很短,并且后续一直进位的状况:
[9] [1,9,9,9,9,9,9,9,9,9]
因此咱们能够定义一个叫carry
的变量来表示是否须要进位。
class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode head1 = l1; ListNode head2 = l2; ListNode newHead = new ListNode(0); ListNode head3 = newHead; // 进位标志 boolean carry = false; while (head1 != null || head2 != null) { // 获取对应位置的值而后相加 int x = (head1 != null) ? head1.val : 0; int y = (head2 != null) ? head2.val : 0; int sum = carry ? (x + y + 1) : (x + y); // 处理进位 if (sum >= 10){ sum -= 10; carry = true; } else { carry = false; } // 新增节点 head3.next = new ListNode(sum % 10); head3 = head3.next; if (head1 != null) head1 = head1.next; if (head2 != null) head2 = head2.next; } if (carry) { head3.next = new ListNode(1); } return newHead.next; } }
嗯,这下就没什么问题了。😜
若是你有更好的解法,欢迎留言讨论~