每日一題-兩數相加 II

今天是2020年4月14日,星期二。

題目描述

給你兩個 非空 鏈表來代表兩個非負整數。數字最高位位於鏈表開始位置。它們的每個節點只存儲一位數字。將這兩數相加會返回一個新的鏈表。

你可以假設除了數字 0 之外,這兩個數字都不會以零開頭。
 
進階:
如果輸入鏈表不能修改該如何處理?換句話說,你不能對列表中的節點進行翻轉。
 
示例:

輸入:(7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 8 -> 0 -> 7

題目思路

看到這兩個鏈表後,可以想到將每個鏈表轉化爲一個數字,進而將兩個鏈表的相加轉化爲兩個數字的加和。但在Java中存在一個問題,如果鏈表很長,可能轉換爲數字後,其範圍大於了int最大的表示範圍,甚至超過了long類型,此時就會出現問題,說明在大範圍數據的時候不適用。後面借用了List去存儲了鏈表中的數據,進行了求和,但是這個方法還是比較低效。

高效一些的方法則是可以藉助棧的特性,遍歷每個鏈表並加入棧中,則"高位"的數字位於棧底,最後相加;"低位"的數字位於棧頂,先相加。最後轉換爲結果需要的list即可。

參考代碼

  • 自己寫的低效代碼
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        int length1 = 0;
        int length2 = 0;
        ListNode tmp1 = l1;
        ListNode tmp2 = l2;
        List<Integer> value1List = new ArrayList<>();
        List<Integer> value2List = new ArrayList<>();

        while (tmp1 != null) {
            length1++;
            value1List.add(tmp1.val);
            tmp1 = tmp1.next;
        }
        while (tmp2 != null) {
            length2++;
            value2List.add(tmp2.val);
            tmp2 = tmp2.next;
        }
        int min = Math.min(length1, length2);
        int max = Math.max(length1, length2);

        List<Integer> list = new ArrayList<>();
        boolean isJinWei = false;

        int index = 0;
        if (min == length1) {
            for (int i = min - 1, j = max - 1; i >= 0; i--, j--) {
                int current = value1List.get(i) + value2List.get(j);
                if (isJinWei) {
                    current += 1;
                    isJinWei = false;
                }
                if (current >= 10) {
                    current -= 10;
                    isJinWei = true;
                }
                list.add(index, current);
                index++;
            }
            for (int i = max - min - 1; i >= 0; i--) {
                int current = value2List.get(i);
                if (isJinWei) {
                    current++;
                    isJinWei = false;
                }
                if (current >= 10) {
                    current -= 10;
                    isJinWei = true;
                }
                list.add(index, current);
                index++;
            }
            if (isJinWei) {
                list.add(1);
            }
        } else {
            for (int i = min - 1, j = max - 1; i >= 0; i--, j--) {
                int current = value1List.get(j) + value2List.get(i);
                if (isJinWei) {
                    current += 1;
                    isJinWei = false;
                }
                if (current >= 10) {
                    current -= 10;
                    isJinWei = true;
                }
                list.add(index, current);
                index++;
            }
            for (int i = max - min - 1; i >= 0; i--) {
                int current = value1List.get(i);
                if (isJinWei) {
                    current++;
                    isJinWei = false;
                }
                if (current >= 10) {
                    current -= 10;
                    isJinWei = true;
                }
                list.add(index, current);
                index++;
            }
            if (isJinWei) {
                list.add(1);
            }
        }

        ListNode head = new ListNode(-1);
        for (int i = 0; i < list.size(); i++) {
            ListNode node = new ListNode(list.get(i));
            node.next = head.next;
            head.next = node;
        }

        return head.next;
    }
  • 參考甜姨的stack法的實例代碼
/**
 * 使用棧的特性存儲數據
 *
 * @param l1
 * @param l2
 * @return
 */
public ListNode addTwoNumbers2(ListNode l1, ListNode l2) {
    Stack<Integer> stack1 = new Stack<>();
    Stack<Integer> stack2 = new Stack<>();
    while (l1 != null) {
        stack1.push(l1.val);
        l1 = l1.next;
    }
    while (l2 != null) {
        stack2.push(l2.val);
        l2 = l2.next;
    }

    int carry = 0;
    ListNode head = null;
    while (!stack1.isEmpty() || !stack2.isEmpty() || carry > 0) {
        int value1 = stack1.isEmpty() ? 0 : stack1.pop();
        int value2 = stack2.isEmpty() ? 0 : stack2.pop();
        int result = value1 + value2 + carry;
        ListNode node = new ListNode(result % 10);
        node.next = head;
        head = node;
        carry = result / 10;
    }

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