題目是:給兩個非空的鏈表,表示兩個非負整數。它們每位數都是按照逆序的方式存儲,并且每一個節點只能存儲一位數字。現在兩個數相加,并且以相同的形式返回一個表示和的鏈表。
首先回顧一下,什么是鏈表?鏈表是一種數據結構,由一系列的節點組成,每一個節點有兩個部分:一部分是存儲數據元素,一部分是存儲下一個節點地址的指針。
在解答這個題目過程中還運用到進位,進位是一種運算形式,加法運算中,每一數位上的數相加滿十,則用一個高位上的數記其和1。
既然是鏈表運算,就先定義一個鏈表節點的構造函數:
class ListNode {constructor(val, next = null) {this.val = val;this.next = next;}
}
在運算的函數里面,首先要定義一個頭節點:
let Head = new ListNode(0);
定義一個表示當前節點的變量:
let current = Head;
進位標志為:
let carry = 0;
遍歷鏈表:
while (l1 !== null || l2 !== null) { // 當兩個鏈表中任意一個不為空時繼續循環let n1 = l1 === null ? 0 : l1.val; // 若l1為空,則取值為0let n2 = l2 === null ? 0 : l2.val; // 若l2為空,則取值為0let sum = n1 + n2 + carry; // 計算當前位和進位之和carry = Math.floor(sum / 10); // 計算新的進位current.next = new ListNode(sum % 10); // 創建新節點,并設置其值為和除以10的余數current = current.next; // 移動到下一個節點if (l1 !== null) l1 = l1.next; // 移動l1指針if (l2 !== null) l2 = l2.next; // 移動l2指針}
如果進位標志大于0,那就在鏈表后面添加一個新的節點:
if (carry > 0) {current.next = new ListNode(carry);}
最后返回鏈表。
完整代碼如下:
class ListNode {constructor(val, next = null) {this.val = val;this.next = next;}
}/*** @param {ListNode} l1* @param {ListNode} l2* @return {ListNode}*/
var addTwoNumbers = function(l1, l2) {
let dummyHead = new ListNode(0); // 創建一個虛擬頭節點let current = dummyHead; // 當前節點指針,初始指向虛擬頭節點let carry = 0; // 進位標志while (l1 !== null || l2 !== null) { // 當兩個鏈表中任意一個不為空時繼續循環let n1 = l1 === null ? 0 : l1.val; // 若l1為空,則取值為0let n2 = l2 === null ? 0 : l2.val; // 若l2為空,則取值為0let sum = n1 + n2 + carry; // 計算當前位和進位之和carry = Math.floor(sum / 10); // 計算新的進位current.next = new ListNode(sum % 10); // 創建新節點,并設置其值為和除以10的余數current = current.next; // 移動到下一個節點if (l1 !== null) l1 = l1.next; // 移動l1指針if (l2 !== null) l2 = l2.next; // 移動l2指針}// 如果最后還有進位,則在鏈表末尾添加一個新的節點表示這個進位if (carry > 0) {current.next = new ListNode(carry);}return dummyHead.next;
};