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
分别给两个链表来表示两个非零整数,然后返回该两个整数的和的链表形式,注意这里链表的排列顺序和整数的每一位数字排列是相反的,即排第一位的是个位。
思路很简单,就是自己处理进位即可。容易犯的一个错误是,当我们运算完最大一位时,此时还有进位,要额外在链表中多加一位“1”。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode answer = new ListNode(0), next = answer;
boolean isAdd = false;
while ((l1 != null) || (l2 != null)) {
int sum = 0;
if (l1 != null) {
sum += l1.val;
l1 = l1.next;
}
if (l2 != null) {
sum +=l2.val;
l2 = l2.next;
}
if (isAdd) {
sum += 1;
isAdd = false;
}
if (sum >= 10) {
sum -= 10;
isAdd = true;
}
else
isAdd = false;
next.next = new ListNode(sum);
next = next.next;
}
if (isAdd) {
next.next = new ListNode(1);
next = next.next;
}
return answer.next;
}
}
里面已经给出了链表的类,按着写就是了。
因为是单个循环即可解决,时间复杂度为O(n),RunTime为5ms。
而在网上所看到的答案如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int carry =0;
ListNode newHead = new ListNode(0);
ListNode p1 = l1, p2 = l2, p3=newHead;
while(p1 != null || p2 != null){
if(p1 != null){
carry += p1.val;
p1 = p1.next;
}
if(p2 != null){
carry += p2.val;
p2 = p2.next;
}
p3.next = new ListNode(carry%10);
p3 = p3.next;
carry /= 10;
}
if(carry==1)
p3.next=new ListNode(1);
return newHead.next;
}
}
这段代码的RunTime为4ms。
有趣的是,网上的代码第一次提交时的RunTime为9ms,我一开始以为是里面的除法和取余所导致的,但是后来又提交多次,时间就回到稳定的4ms了。
在提交这些代码时,leetCode说最近在改进Java的RunTime计算时间,建议过几天再提交测试一下。
无论如何,1ms的差距并不算很明显。但是,更优化的代码无疑更简洁易读,而且代码行数更少,还是需要好好学习研究。