1 題目描述
給出兩個 非空 的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式存儲的,並且它們的每個節點只能存儲 一位 數字。
如果,我們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。
您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。
示例:
輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
原因:342 + 465 = 807
2 解題思路
原文鏈接:https://leetcode.wang/leetCode-2-Add-Two-Numbers.html
就是兩個鏈表表示的數相加,這樣就可以實現兩個很大的數相加了,無需考慮數值 int ,float 的限制了。
鏈表最左邊表示個位數,代表 342 + 465 =807 。
首先每一位相加肯定會產生進位,我們用carry表示。
進位最大會是1,因爲最大的情況無非是9 + 9 + 1= 19,也就是兩個最大的數相加,再加進位,這樣最大是19,不會產生進位2。
具體實現步驟如下:
-
初始化一個節點的頭,dummy head, 但是這個頭不存儲數字,並且將cur指向它
-
初始化進位carry爲0
-
初始化p和q分別爲給定的兩個鏈表l1 和l2 的頭,也就是個位
-
進行循環,直到l1 和 l2 全部到達null
(1) 設置x爲p節點的值,如果p已經到達了null,設置x 爲0
(2)設置y爲q節點的值,如果q已經到達了null,設置y爲0
(3)設置sum = x + y + carry
(4)更新carry = sum/10— 這裏是取整 作爲進位
(5)創建一個值爲sum mod 10 的節點,並將curr 的next 指向它,同時curr指向變爲當前的新節點
(6)向前移動p和q -
判斷carry 是否等於1, 如果等於1,在鏈表末尾增加一個爲1的節點
-
返回dummy head 的next,也就是個位數開始的地方
初始化的節點 dummy head 沒有存儲值,最後返回 dummy head 的next。這樣的好處是不用單獨對head 進行判斷改變值。
也就是如果一開始的head 就是代表個位數,那麼開始初始化的時候並不知道它的值是多少,所以還需要在進入循環前單獨對它的值進行更正,不能像現在一樣只用一個循環簡潔。
3 解決代碼
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
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 = x + y + carry;
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;
}
}