题目:
You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
一开始看到这题的时候就联想到怎么合并两个有序链表为一个有序链表,于是按照这种思路:当两个链表不为空的时候,从第一个节点开始,带进行相加,结果存在一个新的链表里面。直到其中一个链表为空,让结果链表和不为空的链表相接起来,就样就轻轻松松搞定了。真的是这样吗?一测试发现,没有考虑当两个链表不为空时的最后一次相加有进位的情况,于是在原有代码添加补丁,首先进行判断如果有进位,将进位加到这时候不为空的链表的当前节点,如果一直有进位就一直遍历,如果某个时刻没有进位,就将结果链表和不为空的链表相接,返回结果。
经过不断添补写出了史上最繁杂的代码,代码很多但是思路是很清晰的:
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
if(l1==null)
return l2;
else if(l2==null)
return l1;
ListNode fakeNode=new ListNode(-1);
ListNode cur=fakeNode;
int val=0;
int add=0;
while(l1!=null&&l2!=null)
{
val=l1.val+l2.val+add;
if(val>=10)
{
add=val/10;
val=val%10;
}
else {
add=0;
}
ListNode temp=new ListNode(val);
cur.next=temp;
cur=cur.next;
l1=l1.next;
l2=l2.next;
}
if(add==1)//当其中一个链表遍历完后,但是前一次存在进位 的情况
{
while(l1!=null)
{
val=l1.val+add;
if(val>=10)
{
add=val/10;
val=val%10;
}
else {
add=0;
}
ListNode temp=new ListNode(val);
cur.next=temp;
l1=l1.next;
cur=cur.next;
if(add<1)//如果不存在进位,就停止遍历,让cur指向l1链表后面部分直接返回
{
cur.next=l1;
return fakeNode.next;
}
}
while(l2!=null)
{
val=l2.val+add;
if(val>=10)
{
add=val/10;
val=val%10;
}
else {
add=0;
}
ListNode temp=new ListNode(val);
cur.next=temp;
cur=cur.next;
l2=l2.next;
if(add<1)
{
cur.next=l2;
return fakeNode.next;
}
}
if(add>0)
{
ListNode temp=new ListNode(add);
cur.next=temp;
cur.next.next=null;
return fakeNode.next;
}
}
else {
cur.next=l1==null?l2:l1;
}
return fakeNode.next;
}
虽然算法效率是可以的,但是实在代码太多了,于是重新整理思路,代码进行了精简,同样新建一个链表存放结果,只有两个链表有不为空或是有进位就一直循环下去,出现一个链表为空另一个链表不为空的情况将空的链表的值用0表示。
好的!!代码如下:
public static ListNode addTwoNumbers2(ListNode l1, ListNode l2) {
ListNode fakeNode=new ListNode(-1);
ListNode cur=fakeNode;
int carry=0;//进位
int num1=0,num2=0,sum=0;//两个相加节点的取值
ListNode newNode=null;
while(l1!=null||l2!=null||carry!=0)
{
num1=l1==null?0:l1.val;
num2=l2==null?0:l2.val;
sum=num1+num2+carry;
if(sum>=10)
{
carry=sum/10;
sum=sum%10;
}
else if(sum>0&&sum<10){
carry=0;
}
newNode=new ListNode(sum);
cur.next=newNode;
cur=cur.next;
l1=l1!=null?l1.next:null;
l2=l2!=null?l2.next:null;
}
cur.next=null;
return fakeNode.next;
}
你知道下面这句话为什么这样写吗?
else if(sum>0&&sum<10)