1. 程式人生 > >【Leetcode問題搬運翻譯】Add two numbers

【Leetcode問題搬運翻譯】Add two numbers

/**

*本篇文章均為本人翻譯,原問題連結點選開啟連結

*/

問題描述:你被給予兩個非空連結串列,分別代表兩個非負整數。這些數字以倒序的方式儲存並且他們的每個節點都包含一個數字。新增兩個數字,並將其作為連結串列返回。

你可以假設這兩個數字第一位不為0,除了0本身。

輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)

輸出: 7 -> 0 -> 8

例子:新增的兩個數:342+465=708 有進位就加一


 

思路:

正如你如何在紙面上計算兩個數字一樣,我們首先從最低位加起,這就是l1l2連結串列的頭部。由於每個數字都排布在09之間,加和兩個數可能會溢位,例如

5+7=12。在這種情況下,我們把當前的數字設定為2,並且把進位設定為1帶入下一個迴圈,進位一定是0或者1,因為兩個數的最大可能加和(包括進位)為9+9+1=19


虛擬碼如下:

*將當前節點初始化為返回列表的虛擬頭

*初始化進位為0

*將l1和l2的頭分別初始化為p和q

*遍歷l1和l2直到你到達了底部

      #把x設定為節點p的值。如果p到達了l1的底部,x為0

      #把y設定為節點q的值。如果q到達了l2的底部,y為0

      #設定sum=x+y+進位

      #更新進位=sum/10

      #建立一個新的節點,並且賦給他sum除10取餘的值,然後將其設定為當前節點的下一個節點,再將當前節點轉發到下一個節點。

      #p和q同時推進

*檢測,進位是否為1,如果是的話,將一個新的節點加上數字1到返回列表中。

*返回虛擬頭的下一個節點

注意我們使用虛擬頭簡化程式碼。如果沒有一個虛擬頭,您必須編寫額外的條件語句來初始化頭部的值。對下列情況要格外小心

測試案例 解釋
l1=[0,1]
l2=[0,1,2]l2=[0,1,2]
一個連結串列比另一個連結串列長
l1=[]
l2=[0,1]l2=[0,1]


一個連結串列為空,是空連結串列
l1=[9,9]
l2=[1]l2=[1]
這個總數在最後可能有一個額外的進位,這很容易忘記。


Java程式碼:

public ListNode
addTwoNumbers(ListNode l1, ListNode l2) { ListNode dummyHead = new ListNode(0); ListNode p = l1, q = l2, curr = dummyHead; int carry = 0; while (p != null || q != null) { int x = (p != null) ? p.val : 0; int y = (q != null) ? q.val : 0; int sum = carry + x + y; carry = sum / 10; curr.next = new ListNode(sum % 10); curr = curr.next; if (p != null) p = p.next; if (q != null) q = q.next; } if (carry > 0) { curr.next = new ListNode(carry); } return dummyHead.next; }
複雜性分析:

時間複雜性:假設m,n分別代表l1l2的長度,上訴演算法最多疊加max(m,n)

空間複雜性:新連結串列的長度最多是max(m,n)+1

新問題:

如果連結串列中的資料不是倒序存放呢?

例子:(3->4->2+(4->6->5)=8->0->7