很久沒做算法題了,准備重操舊業,於是刷了一波LeetCode,看到一個比較經典的鏈表算法題,分享出來。
題目
給定兩個非空鏈表來表示兩個非負整數。位數按照逆序方式存儲,它們的每個節點只存儲單個數字。將兩數相加返回一個新的鏈表。 你可以假設除了數字 0 之外,這兩個數字都不會以零開頭。 示例: 輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 輸出:7 -> 0 -> 8 原因:342 + 465 = 807
鏈表結構
class ListNode{ int val; ListNode next; ListNode(int x) { val = x; } }
三個需要操作的鏈表圖示(其實可以使用兩個鏈表以節省空間,但是時間效率就會降低,題目沒有定義鏈表長度)
這都是沒有進位而且輸入鏈表長度相同且結果不影響輸出鏈表長度的情況,如果需要進位,或者輸入鏈表的長度不同,那么也需要考慮進去。
思路
我們很容易想到就是從左往右依次遍歷兩個輸入的List,對這兩個List的Node對應加和,但是要注意的就是進位問題和這里的數字是反向的,注意進位判斷,其實這個反向的條件對我們是有利的,因為這和我們平常加法算數是一致的,從低位到高位,這里只不過改成從左往右了,原理都是一樣的。
還要注意輸入鏈表的最后一個結點位置,我們用循環來遍歷的時候就需要每一次都檢查鏈表是不是最后一個結點,而且兩個鏈表長度未必一樣,注意空引用判斷。
主要邏輯代碼
1 public static ListNode addTwoNumbers(ListNode l1, ListNode l2) { 2 ListNode l4 = new ListNode(0); 3 ListNode l3 = new ListNode(0); 4 l4.next = l3; 5
6 while(l1 != null || l2 != null){ 7 int val1 = l1 == null ? 0 : l1.val; 8 int val2 = l2 == null ? 0 : l2.val; 9 //創建新的結點
10 ListNode l5 = new ListNode(0); 11 //進位
12 l5.val = (val1 + val2 + l3.val)/10; 13 //當前位
14 l3.val = (val1 + val2 + l3.val)%10; 15
16 //如果是最后一次循環,且最后一位為0,那么就要除去這個結點
17 if(l5.val == 0 && (l1!= null ? l1.next:null) == null && (l2 != null ? l2.next : null) == null){ 18 l3.next = null; 19 }else{ 20 l3.next = l5; 21 l3 = l5; 22 } 23
24 //跳轉指針
25 l1 = l1 == null ? null : l1.next; 26 l2 = l2 == null ? null : l2.next; 27 } 28 return l4.next; 29 }
測試代碼
class ListNode{ int val; ListNode next; ListNode(int x) { val = x; } } public class Test{ public static void main(String[] args) { ListNode l1 = new ListNode(2); ListNode l2 = new ListNode(3); ListNode l3 = new ListNode(4); l1.next=l2; l2.next=l3; l3.next = null; ListNode l4 = new ListNode(5); ListNode l5 = new ListNode(6); ListNode l6 = new ListNode(4); l4.next = l5; l5.next = l6; l6.next = null; printList(addTwoNumbers(l1,l4)); } public static ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode l4 = new ListNode(0); ListNode l3 = new ListNode(0); l4.next = l3; while(l1 != null || l2 != null){ int val1 = l1 == null ? 0 : l1.val; int val2 = l2 == null ? 0 : l2.val; //創建新的結點
ListNode l5 = new ListNode(0); //進位
l5.val = (val1 + val2 + l3.val)/10; //當前位
l3.val = (val1 + val2 + l3.val)%10; //如果是最后一次循環,且最后一位為0,那么就要除去這個結點
if(l5.val == 0 && (l1!= null ? l1.next:null) == null && (l2 != null ? l2.next : null) == null){ l3.next = null; }else{ l3.next = l5; l3 = l5; } //跳轉指針
l1 = l1 == null ? null : l1.next; l2 = l2 == null ? null : l2.next; } return l4.next; } public static void printList(ListNode l){ while(l!=null){ System.out.print("->"); System.out.print(l.val); l = l.next; } } }