题目:
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
示例1:
解法一:链表实现(python)
class Solution:
def addTwoNumbers(self, l1:ListNode, l2:ListNode) -> ListNode
#初始化个位节点,先不做进位
newPoint = ListNode(l1.val+l2.val)
#rt用来作为最后return的节点,tp用来遍历节点
rt,tp=newPoint,newPoint
#l1,l2只要后面还有节点,就继续往后遍历;或者新链表还需要继续往后进位
while(l1 and (l1.next !=None))or(l2 and (l2.next !=None))
#等价于 if l1: l1 = l1.next; 这里用来判断l1是否为None,不为None的话就让它成为它的下一个节点。
l1,l2 = l1.next if l1 else l1, l2.next if l2 else l2
tmpsum = (l1.val if l1 else 0) + (l2.val if l2 else 0 )
#计算新链表下个节点的值(当前)
tp.next = ListNode(tp.val//10 + tmpsum)
#新链表当前节点的值取个位
tp.val %= 10
#新链表往后遍历一个节点
tp=tp.next
return rt
解法二(java)官方解答
思路与算法
由于输入的两个链表都是逆序存储数字的位数的,因此两个链表中同一位置的数字可以直接相加。
我们同时遍历两个链表,逐位计算它们的和,并与当前位置的进位值相加。具体而言,如果当前两个链表处相应位置的数字为 n1,n2进位值为carry,则它们的和为n1+n2+carry;其中,答案链表处相应位置的数字为(n1+n2+carry)mod10,而新的进位值为(n1+n2+carry)/10向下取整
如果两个链表的长度不同,则可以认为长度短的链表的后面有若干个0 。
此外,如果链表遍历结束后,有carry> 0,还需要在答案链表的后面附加一个节点,节点的值为carry。
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head = null, tail = null;
int carry = 0;
while (l1 != null || l2 != null) {
int n1 = l1 != null ? l1.val : 0;
int n2 = l2 != null ? l2.val : 0;
int sum = n1 + n2 + carry;
if (head == null) {
head = tail = new ListNode(sum % 10);
} else {
tail.next = new ListNode(sum % 10);
tail = tail.next;
}
carry = sum / 10;
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
}
if (carry > 0) {
tail.next = new ListNode(carry);
}
return head;
}
}
解法三:看到老师里写的一个解法(0ms)
为什么速度这么快,没学java的我暂时不晓得。
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
return this.addTwoNumbersXX(l1,l2,0);
}
public ListNode addTwoNumbersXX(ListNode l1, ListNode l2,int data) {
if (l1==null && l2==null){ //两个链表同时为空
return data==0?null:new ListNode(data);//返回节点
}
if (l1!=null){
data+=l1.val;
l1=l1.next;//继续循环
}
if (l2!=null){
data+=l2.val;
l2=l2.next;//继续循环
}
return new ListNode(data%10,addTwoNumbersXX(l1,l2,data/10));
}
}