1. 程式人生 > >Lintcode 連結串列求和 系列

Lintcode 連結串列求和 系列

問題1 描述
你有兩個用連結串列代表的整數,其中每個節點包含一個數字。數字儲存按照在原來整數中相反的順序,使得第一個數字位於連結串列的開頭。寫出一個函式將兩個整數相加,用連結串列形式返回和。

樣例
給出兩個連結串列 3->1->5->null 和 5->9->2->null,返回 8->0->8->null

分析:
建立一個新的連結串列來記錄每次的和,使用啞節點表示新連結串列的頭。
需要考慮的問題
1:
兩個連結串列長度不一樣,比如
3->10->null
5->11->9->null
和是8->1->1->1->null
2:
進位的處理用到%和//

"""
Definition of ListNode
class ListNode(object):
    def __init__(self, val, next=None):
        self.val = val
        self.next = next
"""
def addlist(l1,l2):
	dummy=ListNode(0)
	current=dummy
	flag=0
	while l1 or l2:
		if l1:
			x=l1.val
			l1=l1.next
		else:
			x=0
		if l2:
			y=l2.val
			l2=l2.next
		else:
			y=0
		sum=x+y+flag
		current.next=ListNode(sum%10)
		flag=sum//10
		current=current.next
	if flag==1: #最後一個節點是否需要進位
		current=current.next
		return dummy.next
	else:
		return dummy.next

問題2 描述
假定用一個連結串列表示兩個數,其中每個節點僅包含一個數字。假設這兩個數的數字順序排列,請設計一種方法將兩個數相加,並將其結果表現為連結串列的形式。
樣例
給出 6->1->7 + 2->9->5。即,617 + 295。
返回 9->1->2。即,912 。

分析:
上一題是從左往右進位,這裡是右往左進位。
最直觀的方法是翻轉連結串列,然後按照上一題中的方法求解。
關於翻轉連結串列,我的另一篇文章有具體實現和解釋

def reverse(head):
	p=head
	q=head.next
	head.next=None
	while q:	
		r=q.next
		q.next=p
		p=q
		q=r
	newhead=p
	return newhead		
def addLinkedlist2(l1,l2):
	newl1=reverse(l1)
	newl2=reverse(l2)
	dummy=ListNode(0)
	current=dummy
	flag=0
	while newl1 or newl2:
		if newl1:
			x=newl1.val
			newl1=newl1.next
		else:
			x=0
		if newl2:
			y=newl2.val
			newl2=newl2.next
		else:
			y=0
		sum=x+y+flag
		current.next=ListNode(sum%10)
		flag=sum//10
		current=current.next
	if flag:
		current.next=ListNode(flag)
		return reverse(dummy.next)
	else:
		return reverse(dummy.next)