鏈表相加是指將兩個鏈表表示的數(shù)相加,得到一個新的鏈表表示的結(jié)果。假設(shè)兩個鏈表的每個節(jié)點都表示一位數(shù)字,且是逆序存儲的(即鏈表的尾部表示數(shù)字的最高位),那么可以按照以下步驟來實現(xiàn)鏈表相加:
- 定義一個 ListNode 類來表示鏈表的節(jié)點,其中包含一個
val屬性表示節(jié)點的值,以及一個next屬性表示指向下一個節(jié)點的指針。 - 定義一個
addTwoNumbers函數(shù),接收兩個鏈表作為參數(shù)。 - 創(chuàng)建一個新鏈表
result,表示相加的結(jié)果。同時定義兩個指針p和q分別指向兩個鏈表的頭節(jié)點,以及一個指針curr指向結(jié)果鏈表的頭節(jié)點。 - 對于每一位數(shù)字,將
p和q指向的節(jié)點的值相加,并加上前一位數(shù)字的進位值,得到一個新的進位值和相加后的值。將該值存儲到結(jié)果鏈表中,并將指針p、q和curr向后移動。 - 如果有任何一個鏈表已經(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ù)中,初始化了兩個指針 p 和 q 分別指向兩個鏈表的頭節(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 } }
}