鏈表相加是指將兩個鏈表表示的數(shù)相加,得到一個新的鏈表表示的結(jié)果。假設(shè)兩個鏈表的每個節(jié)點都表示一位數(shù)字,且是逆序存儲的(即鏈表的尾部表示數(shù)字的最高位),那么可以按照以下步驟來實現(xiàn)鏈表相加:

  1. 定義一個 ListNode 類來表示鏈表的節(jié)點,其中包含一個 val 屬性表示節(jié)點的值,以及一個 next 屬性表示指向下一個節(jié)點的指針。
  2. 定義一個 addTwoNumbers 函數(shù),接收兩個鏈表作為參數(shù)。
  3. 創(chuàng)建一個新鏈表 result,表示相加的結(jié)果。同時定義兩個指針 pq 分別指向兩個鏈表的頭節(jié)點,以及一個指針 curr 指向結(jié)果鏈表的頭節(jié)點。
  4. 對于每一位數(shù)字,將 pq 指向的節(jié)點的值相加,并加上前一位數(shù)字的進位值,得到一個新的進位值和相加后的值。將該值存儲到結(jié)果鏈表中,并將指針 pqcurr 向后移動。
  5. 如果有任何一個鏈表已經(jīng)到達了末尾,則在計算下一位數(shù)字時只考慮另一個鏈表的值,并將前一位的進位值加到結(jié)果中。如果計算完所有位數(shù)后,前一位仍然有進位,則需要將進位值添加到結(jié)果鏈表的末尾。

下面是具體的實現(xiàn)代碼:

class ListNode {
    constructor(val, next = null) {
        this.val = val;
        this.next = next;
    }
}

function addTwoNumbers(l1, l2) {
    let p = l1;
    let q = l2;
    let carry = 0; // 進位值
    let result = new ListNode(0);
    let curr = result;

    while (p !== null || q !== null) {
        const x = p ? p.val : 0;
        const y = q ? q.val : 0;
        const sum = x + y + carry;
        carry = Math.floor(sum / 10);
        curr.next = new ListNode(sum % 10);
        curr = curr.next;
        if (p) p = p.next;
        if (q) q = q.next;
    }

    if (carry > 0) {
        curr.next = new ListNode(carry);
    }

    return result.next;
}

在上述代碼中,首先定義了一個 ListNode 類來表示鏈表的節(jié)點。在 addTwoNumbers 函數(shù)中,初始化了兩個指針 pq 分別指向兩個鏈表的頭節(jié)點,同時初始化了一個進位值 carry 和結(jié)果鏈表 result。然后,循環(huán)遍歷兩個鏈表,計算每一位數(shù)字的相加結(jié)果,并將結(jié)果存儲到結(jié)果鏈表中。最后,如果前一位數(shù)字有進位,則需要將進位值添加到結(jié)果鏈表的末尾。

可以使用上述代碼的時間復(fù)雜度是 $O(\max(m,n))$,其中 $m$ 和 $n$ 分別是兩個鏈表的長度。這是因為需要遍歷兩個鏈表,并對每一位數(shù)字進行相加。空間復(fù)雜度也是 $O(\max(m,n))$,因為需要創(chuàng)建一個新的鏈表來存儲相加的結(jié)果。

下面是一個示例,演示如何使用上述代碼來計算鏈表相加:

const l1 = new ListNode(3, new ListNode(4, new ListNode(3)));
const l2 = new ListNode(5, new ListNode(6, new ListNode(4)));
const result = addTwoNumbers(l1, l2);
console.log(result);

上述示例中輸出的結(jié)果為:

ListNode {
  val: 8,
  next: ListNode { val: 0, next: ListNode { val: 8, next: null } }
}