兩數相加(java版本)


 

(一)、單鏈表實現

package com.lin.leetcode.addTwoNumbers;

/**
 * Created by Yaooo on 2019/8/26.
 */
public class ListNode {
    int data;
    ListNode next;
    ListNode(int data){
        this.data = data;
    }
}

 

package com.lin.leetcode.addTwoNumbers;

import java.util.List;

/**
 * Created by Yaooo on 2019/8/25.
 */
public class SingleLinkedList{

    public int size;
    public ListNode head;

    // head|next ->null
    public SingleLinkedList(){
        size = 0;
        head = null;
    }

    // head -> a|next ->b|next ->null
    public void addData(int obj){
        ListNode node = new ListNode(obj);
        if(size == 0){
            head = node;
            node.data= obj;
        }else{
            node.next = head;
            head = node;
            node.data = obj;
        }
        size++;
    }
    // head -> a|next ->b|next ->c|next ->null
    public boolean deleteData(int value){
        if (size == 0){
            return false;
        }
        ListNode current = head;
        ListNode previous = head;
        while(current.data!=value){
            if (current.next == null){
                return false;
            }else{
                previous = current;
                current = current.next;
            }
        }
        if(current == head){
            head = current.next;
            size--;
        }else {
            previous.next = current.next;
            size--;
        }
        return true;
    }

    public void display(){
        ListNode node = head;
        while (node!=null){
            if (node.next==null){
                System.out.print(node.data );
                node = node.next;
            }else{
                System.out.print(node.data + "->");
                node = node.next;
            }
        }
    }

    public static void main(String[] args){
        SingleLinkedList list = new SingleLinkedList();
        list.addData(1);
        list.addData(2);
        list.addData(5);
        list.deleteData(5);
        list.display();
    }

}

 

實現單鏈表兩數相加:

思路

我們使用變量來跟蹤進位,並從包含最低有效位的表頭開始模擬逐位相加的過程。

 

 

圖1,對兩數相加方法的可視化: 342 + 465 = 807342+465=807,每個結點都包含一個數字,並且數字按位逆序存儲。

算法

就像你在紙上計算兩個數字的和那樣,我們首先從最低有效位也就是列表 l1l1 和 l2l2 的表頭開始相加。由於每位數字都應當處於 0 \ldots 90…9 的范圍內,我們計算兩個數字的和時可能會出現 “溢出”。例如,5 + 7 = 125+7=12。在這種情況下,我們會將當前位的數值設置為 22,並將進位 carry = 1carry=1 帶入下一次迭代。進位 carrycarry 必定是 00 或 11,這是因為兩個數字相加(考慮到進位)可能出現的最大和為 9 + 9 + 1 = 199+9+1=19。

偽代碼如下:

  • 將當前結點初始化為返回列表的啞結點。
  • 將進位 carry 初始化為 0。
  • 將 p 和 q 分別初始化為列表 l1 和 l2 的頭部。
  • 遍歷列表 l1 和 l2 直至到達它們的尾端。
  1.    將 x 設為結點 p 的值。如果 pp 已經到達 l1 的末尾,則將其值設置為 0。
  2.    將 y 設為結點 qq 的值。如果 qq 已經到達 l2 的末尾,則將其值設置為 0。
  3.    設定 sum=x+y+carry。
  4.    更新進位的值,carry=sum/10。
  5.    創建一個數值為(sum mod 10) 的新結點,並將其設置為當前結點的下一個結點,然后將當前結點前進到下一個結點。
  6.    同時,將 p 和 q 前進到下一個結點。
  • 檢查carry=1 是否成立,如果成立,則向返回列表追加一個含有數字 11 的新結點。
  • 返回啞結點的下一個結點。

請注意,我們使用啞結點來簡化代碼。如果沒有啞結點,則必須編寫額外的條件語句來初始化表頭的值。

請特別注意以下情況:

測試用例 說明

package com.lin.leetcode.addTwoNumbers;

import java.lang.reflect.Array;

/**
 * Created by Yaooo on 2019/8/25.
 */
public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dumpHead = new ListNode(0);
        ListNode p = l1, q = l2, curr = dumpHead;
        int carry = 0;
        while (p != null || q != null) {
            int x = (p != null) ? p.data : 0;
            int y = (q != null) ? q.data : 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 dumpHead.next;
    }

    public static void main(String[] args){
        SingleLinkedList l1 = new SingleLinkedList();
        l1.addData(1);
        l1.addData(2);
        l1.addData(5);
        SingleLinkedList l2 = new SingleLinkedList();
        l2.addData(3);
        l2.addData(2);
        l2.addData(7);
        Solution solution = new Solution();
        ListNode l3 = solution.addTwoNumbers(l1.head,l2.head);
        while (l3!=null){
            if(l3.next == null ){
                System.out.print(l3.data);
                l3 = l3.next;
            }else{
                System.out.print(l3.data+"->");
                l3 = l3.next;
            }
        }
    }
}

復雜度分析

時間復雜度:O(max(m,n)),假設 mm 和 nn 分別表示 l1l1 和 l2l2 的長度,上面的算法最多重復max(m,n) 次。

空間復雜度:O(max(m,n)), 新列表的長度最多為max(m,n)+1。

拓展

如果鏈表中的數字不是按逆序存儲的呢?例如:

(3→4→2)+(4→6→5)=8→0→7


算法引用於鏈接:https://leetcode-cn.com/problems/add-two-numbers/solution/liang-shu-xiang-jia-by-leetcode/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM