题目
You are given two non-empty linked lists representing two non-negative integers. 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.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Example:
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.
解析
题目的意思是输入两个链表,将两个链表的值求和获得一个新的链表。
在拿到这个题目的第一反应是将两个链表分别转换为int数值,例如(2->4->3)转换为342,然后求和之后获得807,再将807重新解析成(7->0->8)。
这种解法在大多数的情况下是没有问题的,但是遇到一些非常极端的输入时会出现问题。例如在输入(9->9->9....x1000个9),(0)的时候,第一个链表转换出来的值明显超出了java基本类型的范围了,那么这时就不能采取这种先求值再求和的方法了。
那么很明显了,题目的目的是考链表的循环以及链表的构造,那么循环两个链表的同时将节点的值求和放入结果链表中,有进位则记录,在下次循环时进位即可:
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
if(l1 == null || l2 ==null){
return null;
}
ListNode first = null ,next = null;
int plus = 0;
while(l1!=null || l2!=null || plus!=0){
int num1 = l1==null? 0 : l1.val;
int num2 = l2==null? 0 : l2.val;
int sum = num1 + num2 +plus;
if(sum>=10){
sum-=10;
plus=1;
}else{
plus=0;
}
if(first==null){
first = new ListNode(sum);
next = first;
}else{
next.next = new ListNode(sum);
next = next.next;
}
if(l1!=null && l1.next!=null){
l1 = l1.next;
}else{
l1 = null;
}
if(l2!=null && l2.next!=null){
l2 = l2.next;
}else{
l2 = null;
}
}
return first;
}
以上代码经过简化以及改进后可以得出以下代码:
public static ListNode addTwoNumbersBetter(ListNode l1, ListNode l2) {
ListNode fakeHead = new ListNode(0);
ListNode curr = fakeHead;
int carry = 0;
while(l1!=null || l2!=null){
int num1 = l1==null? 0 : l1.val;
int num2 = l2==null? 0 : l2.val;
int sum = num1 + num2 + carry;
carry = sum/10;
curr.next = new ListNode(sum%10);
curr = curr.next;
if(l1!=null) l1 = l1.next;
if(l2!=null) l2 = l2.next;
}
if(carry>0){
curr.next = new ListNode(carry);
}
return fakeHead.next;
}