1. 程式人生 > 其它 >【每日Leetcode-第二天】兩數相加

【每日Leetcode-第二天】兩數相加

題目描述

給你兩個 非空 的連結串列,表示兩個非負的整數。它們每位數字都是按照 逆序 的方式儲存的,並且每個節點只能儲存 一位 數字。

請你將兩個數相加,並以相同形式返回一個表示和的連結串列。

你可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。

解題思路

題目要求將兩個連結串列中的元素當做整數相加,返回包含結果的連結串列。 對兩個連結串列進行同時遍歷,將每一位相加,如果出現兩個連結串列長度不一致的情況,那麼在公共長度遍歷完後,單獨遍歷較長的連結串列。最關鍵的問題是處理進位,在計算當前位置的和時要加上上一位的進位值,然後在下次迴圈開始前重新計算進位值。

四種情況

最高位進位是指連結串列長度的最大位數仍然需要向上進位,此時兩個連結串列均已遍歷完。

  1. 兩個連結串列長度相等,並且最高位沒有進位,如[1, 2, 3][4, 5, 6]這兩組元素,和為[5, 7, 9]
  2. 兩個連結串列長度相等,但是最高位有進位,如[1, 2, 3][4, 5, 7]這兩組元素,和為[5, 7, 0, 1]
  3. 兩個連結串列長度不相等,並且最高位沒有進位,如[1, 2, 3][4, 5, 7, 1]這兩組元素, 和為[5, 7, 0, 2]
  4. 兩個連結串列長度不相等,並且最高位有進位,如[1, 2, 3][4, 5, 7, 9]這兩組元素, 和為[5, 7, 0, 0, 1]

解題程式碼

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        // 空的頭結點,用於串聯連結串列
    ListNode resHead = new ListNode();
    // 儲存最近一個被插入節點的前驅節點
    ListNode resPrev = resHead;
    // 最近一個被插入節點
    ListNode resNext = null;
    // 進位值
    int carry = 0;

    while (l1 != null || l2 != null) {
        int cur = 0;

        if (l1 != null && l2 != null) {            // 兩個連結串列都不為空
            cur = l1.val + l2.val + carry;
            l1 = l1.next;
            l2 = l2.next;
        } else if (l1 != null) {                    // l1連結串列不為空,l2為空
            cur = l1.val + carry;
            l1 = l1.next;
        } else {                                    // l2連結串列不為空,l1為空
            cur = l2.val + carry;
            l2 = l2.next;
        }
        
        // 構造新的節點,並且插入連結串列中
        resNext = new ListNode(cur % 10);
        resPrev.next = resNext;
        resPrev = resNext;
        
        // 計算進位值
        carry = cur >= 10 ? 1 : 0;
    }
    
    // 處理最高位進位的情況
    if (carry == 1) {
        resPrev.next = new ListNode(1);
    }
    
    // resHead.next是第一個有效節點
    return resHead.next;
}

題目來源

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/add-two-numbers