LeetCode-2:Add Two Numbers

一、題目

原題鏈接:https://leetcode.com/problems/add-two-numbers/
難度等級:中等

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8

題目翻譯:
給兩個鏈表代表兩個反向存儲的數字,返回他們的和,用鏈表表示。


二、解題方案

據原題的意思,我們想到的方法就是從頭到尾的對L1和L2的每一個非空結點和進位數carry求和。再通過取餘整除10將carry的個位數值賦給新鏈表node = dummy,十位數值更新到下一位的carry初始值。當L1和L2都遍歷完之後,如果carry不爲0,就給node再增加一個值爲carry的結點,即l1和l2求和的最高位。最後,將得到的和用取餘運算從低位到高位採用尾插入法得到相同形式的鏈表。

解題思路圖標說明 :
這裏寫圖片描述

1. 遞歸法

技巧在於如何處理不同長度的數字,以及進位和最高位的判斷。這裏對於不同長度的數字,我們通過將較短的數字補0來保證每一位都能相加。

遞歸寫法的思路比較直接,即判斷該輪遞歸中兩個ListNode是否爲null。

  • 全部爲null時,返回進位值。
  • 有一個爲null時,返回不爲null的那個ListNode和進位相加的值。
  • 都不爲null時,返回 兩個ListNode和進位相加的值。

代碼實現:

// Add Two Numbers(遞歸法-Java版本)
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        return addTwoNumbers(l1, l2, 0, dummy, dummy);
    }

    private ListNode addTwoNumbers(ListNode l1, ListNode l2, int carry, ListNode current, ListNode result) {
        if (l1 == null && l2 == null) {
            if (carry != 0) current.next = new ListNode(carry);
            return result.next;
        } else {
            l1 = (l1 == null) ? new ListNode(0) : l1;
            l2 = (l2 == null) ? new ListNode(0) : l2;
        }
        int sum = l1.val + l2.val + carry;
        carry = sum / 10;
        current.next = new ListNode(sum % 10);

        return addTwoNumbers(l1.next, l2.next, carry, current.next, result);
    }
}

2. 迭代法

思路:
迭代法相比之下因爲需要處理的分支較多,邊界條件的組合比較複雜。過程同樣是對齊相加,不足位補0。

迭代終止條件是兩個ListNode都爲null。

注意:
- 迭代方法操作鏈表的時候要記得手動更新鏈表的指針到next
- 迭代方法操作鏈表時可以使用一個dummy的頭指針簡化操作
- 不可以在其中一個鏈表結束後直接將另一個鏈表串接至結果中,因爲可能產生連鎖進位

代碼實現:

// Add Two Numbers(迭代法-Java版本)
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        int carry = 0;
        int sum = 0;
        ListNode result = new ListNode(0);  // keep node list
        ListNode current = result;          // current pointer
        do {
            sum = (l1 != null ? l1.val : 0) + (l2 != null ? l2.val : 0) + carry;
            current.next = new ListNode(sum % 10);
            carry = sum / 10;
            l1 = l1 != null ? l1.next : null;
            l2 = l2 != null ? l2.next : null;
            current = current.next;
        } while (l1 != null || l2 != null);
        if (carry != 0) current.next = new ListNode(carry);

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