LeetCode-Algorithms #002 Add Two Numbers, Database #176 Second Highest Salary
阿新 • • 發佈:2019-01-13
LeetCode-Algorithms #002 Add Two Numbers
給定兩個非空的以連結串列結構表示的非負整數, 這個結構長這樣:
1 public class ListNode { 2 int val; 3 ListNode next; 4 ListNode(int x) { val = x; } 5 }
這個結構中從低位到高位由外向記憶體儲, 每一層儲存一位數, 題目要求把給定的兩個數求和, 然後用同樣的結構返回結果.
我的思路:
作為一個頭腦淳樸(簡單)的人, 我還是本能的想, 把這兩個數取出來, 加一加, 然後存回去就好了, 事實也是這麼做了
提交程式碼...
執行超時...
是的, 看來蠢人不配通過提交, 這種做法應該是慢得令人髮指了.
那麼, 只好換個想法, 既然這個結構是個位數存在最外面, 一層一層向裡進位, 那麼我們也就一層一層從外往裡加就好了, 嘗試一下:
1 class Solution { 2 public ListNode addTwoNumbers(ListNode l1, ListNode l2) { 3 //先建立一個ListNode作為答案 4 ListNode ans = new ListNode(0); 5 //再建立另一個引用指向同一個物件 6 ListNode temp = ans;7 //當l1和l2內層都不為空的時候 8 while (l1.next != null && l2.next != null) { 9 //計算當前層的和:l1和l2該位的值加上上一位的進位 10 int sum = l1.val + l2.val + temp.val; 11 //因為l1和l2內層都不為空, 使l1和l2都等於其內層 12 l1 = l1.next; 13 l2 = l2.next; 14 //對和取10的餘數, 獲得結果中這一位的值 15 int val = sum % 10; 16 //把和除以10, 獲得進位的值 17 int carry = sum / 10; 18 //對temp賦值 19 temp.val = val; 20 //把進位的值新增到temp的內層 21 temp.next = new ListNode(carry); 22 //使temp的引用向內指一層 23 temp = temp.next; 24 } 25 //上面的迴圈結束後, 只剩下三種可能, 26 //1. l1.next不為null 27 //2. l2.next不為null 28 //3. l1.next,l2.next都為null 29 30 //在第一種情況下, l2.next雖然為null, 但l2.val還沒有被加入最後的結果中 31 while (l1.next != null) { 32 //所以, 我們還是令三者相加 33 int sum = l1.val + l2.val + temp.val; 34 //但是在第一次加過之後就令l2.val = 0, 以免影響後面的迴圈 35 l2.val = 0; 36 //之後l2就不用管了, 令l1等於其內層 37 l1 = l1.next; 38 //後面的部分和第一個迴圈意思一樣 39 int val = sum % 10; 40 int carry = sum / 10; 41 temp.val = val; 42 temp.next = new ListNode(carry); 43 temp = temp.next; 44 } 45 46 //第二種情況下和上面一樣 47 while (l2.next != null) { 48 int sum = l1.val + l2.val + temp.val; 49 l1.val = 0; 50 l2 = l2.next; 51 int val = sum % 10; 52 int carry = sum / 10; 53 temp.val = val; 54 temp.next = new ListNode(carry); 55 temp = temp.next; 56 } 57 58 //到了這裡l1.next和l2.next都為null, 但l1.val和l2.val至少還有一個沒有加入最後的結果中, 59 //也有可能兩個都沒有, 因此還要最後再做一次 60 int sum = l1.val + l2.val + temp.val; 61 int val = sum % 10; 62 int carry = sum / 10; 63 temp.val = val; 64 //最後這次要判斷一下,只有要進位的值不為零的情況下才進位, 否則最後的結果可能會多一個0出來 65 if(carry != 0) { 66 temp.next = new ListNode(carry); 67 } 68 //返回結果 69 return ans; 70 } 71 }
過程中其實碰到了不少預想之外的問題, 感覺寫得也比較囉嗦, 但是總歸是順利實現了:
測試一下大致是個平均水平, 和第一梯隊差距倒是不算太過明顯, 不過看一看強者的提交, 還是讓人心碎:
1 class Solution { 2 public ListNode addTwoNumbers(ListNode l1, ListNode l2) { 3 int carry = 0; 4 ListNode p = l1; 5 ListNode q = l2; 6 ListNode end = l1; 7 while (p != null || q != null) { 8 int sum = carry; 9 if (p!= null && p.next == null) end = p; 10 if (q != null) sum += q.val; 11 if (p != null) sum += p.val; 12 int remainder = sum % 10; 13 carry = sum / 10; 14 if (p!= null) { 15 p.val = remainder; 16 } else { 17 end.next = new ListNode(remainder); 18 end = end.next; 19 } 20 if (p != null) p = p.next; 21 if (q != null) q = q.next; 22 } 23 if (carry != 0) end.next = new ListNode(carry); 24 return l1; 25 } 26 }
總體思路上有一些相通之處(所以也就沒有額外加註釋), 但是完成質量就是天差地別了