[ 熱題 HOT 100] ---2. 兩數相加 -- 數學 ➕ 鏈表

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;

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章