- 題目:
- * 給你兩個 非空 的連結串列,表示兩個非負的整數。它們每位數字都是按照 逆序 的方式儲存的,並且每個節點只能儲存 一位 數字。
- * 請你將兩個數相加,並以相同形式返回一個表示和的連結串列。
- * 你可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。
本題為力扣原題,連結為 https://leetcode.cn/problems/add-two-numbers/,具體例子參照原題給的demo
解題思路:
- 兩個單連結串列中的整數相加,涉及到相加和超過10,需要向前進一位
- 兩個連結串列是否等長需要判斷,如果不等長度,需要先計算等長部分,超出的部分需要根據思路1得出的結果判讀。也就是前一位相加和滿足進位,則繼續計算;反之,則停止
package code.code_02; /** * 力扣原題 https://leetcode.cn/problems/add-two-numbers/ * 題目: * 給你兩個 非空 的連結串列,表示兩個非負的整數。它們每位數字都是按照 逆序 的方式儲存的,並且每個節點只能儲存 一位 數字。 * 請你將兩個數相加,並以相同形式返回一個表示和的連結串列。 * 你可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。 * * demo1 * 輸入:l1 = [2,4,3], l2 = [5,6,4] * 輸出:[7,0,8] * 解釋:342 + 465 = 807. * * demo2 * 輸入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9] * 輸出:[8,9,9,9,0,0,0,1] * * 提示資訊是: * 每個連結串列中的節點數在範圍 [1, 100] 內 * 0 <= Node.val <= 9 * 題目資料保證列表表示的數字不含前導零 * * 解題思路 * 1, 兩兩相加,涉及到和超過10進位數 * 2, 涉及到兩個連結串列長度不等 * 3, 可以補全兩個連結串列,和單獨生成一個新連結串列,但是浪費空間; * 4; 可以把兩數之和壓入長連結串列中,逢十進一 * */ public class NodeListAddTest { //連結串列 public class ListNode { int val; ListNode next; ListNode() {} ListNode(int val) { this.val = val; } ListNode(int val, ListNode next) { this.val = val; this.next = next; } } public int length (ListNode node, int size) { while (node != null) { size++; node = node.next; } return size; } //獲取連結串列長度_遞迴方式 /* public int length (ListNode node, int size) { if (node == null) { return size; } size++; return node.next != null ? length(node.next, size) : size; }*/ public ListNode addTwoNumbers(ListNode l1, ListNode l2) { int length1 = this.length(l1, 0); int length2 = this.length(l2, 0); ListNode lNode = length1 < length2 ? l2 : l1; //長連結串列 ListNode sNode = (lNode == l1) ? l2 : l1; //短連結串列 ListNode prev = null; int carry = 0; //進位 ListNode node = lNode; //根據短連結串列進行迴圈 while (sNode != null) { int total = sNode.val + lNode.val + carry; lNode.val = total % 10; //更新後,長連結串列當前位置的新值 carry = total/10; //如果是1, 則需要進位 if (lNode.next == null) { prev = lNode; } lNode = lNode.next; sNode = sNode.next; } //有可能兩個連結串列長度不一致,此時長連結串列需要繼續. while (lNode != null) { if (carry != 1) { break; } int total = lNode.val + carry; lNode.val = total % 10; //更新後,長連結串列當前位置的新值 carry = total/10; //如果是1, 則需要進位 if (lNode.next == null) { prev = lNode; } lNode = lNode.next; } //如果長連結串列最後一位數處理完還需要進位,則追加節點 if (carry == 1) { ListNode tempNode = new ListNode(carry); prev.next = tempNode; } return node; } // 先設計列印方法,方便檢查逆轉後結果 public void printNode (ListNode node) { if (node == null) { System.out.println("連結串列不存在"); } System.out.println("當前節點的值為: " + node.val); //遞迴的方式逐層列印Node的子節點 if(node.next != null) { printNode(node.next); } } public static void main(String[] args) { NodeListAddTest test = new NodeListAddTest(); //連結串列1 ListNode l1 = test.new ListNode(2); l1.next = test.new ListNode(4); l1.next.next = test.new ListNode(3); //連結串列2 ListNode l2 = test.new ListNode(5); l2.next = test.new ListNode(6); l2.next.next = test.new ListNode(4); ListNode nodeList = test.addTwoNumbers(l1, l2); test.printNode(nodeList); } }
力扣測試結果: