我的LC之路-2. Add Two Numbers
寫在前面:在LeetCode上做的題,代碼基本都是我自己寫的,效率有好有壞,僅供參考。
有少數幾道題苦思冥想做不出來的,可能會借鑒網上大神的解法,然後再自己編寫,借鑒過他人解法的題會有說明。
本人不是算法出身,語言基本靠自學,有任何錯誤理解或者不當舉措,還請各位大俠手下留情並不吝賜教!萬分感謝~
依舊先把題搬一下:
2. Add Two Numbers
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
解題思路:
這道題看著也還不算太難,無非就是註意下進位以及鏈表的使用。話不多說,先上代碼:
1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val;5 * ListNode next; 6 * ListNode(int x) { val = x; } 7 * } 8 */ 9 class Solution { 10 public ListNode addTwoNumbers(ListNode l1, ListNode l2) { 11 ListNode head = new ListNode(0); 12 ListNode result = new ListNode(0); 13 boolean carry = false; 14 int count = findlength(l1, l2);15 this.equalboth(l1,l2,count); 16 for(int i = 0;i<count;i++){ 17 if(i==0) { 18 if(l1.val+l2.val>9) { 19 carry = true; 20 head.val = l1.val+l2.val-10; 21 }else head.val = l1.val+l2.val; 22 result = head; 23 24 }else{ 25 if(carry) { 26 if(l1.val+l2.val+1>9) result.next = new ListNode(l1.val+l2.val-9); 27 else { 28 result.next = new ListNode(l1.val+l2.val+1); 29 carry = false; 30 } 31 }else { 32 if(l1.val+l2.val>9){ 33 result.next = new ListNode(l1.val+l2.val-10); 34 carry = true; 35 } 36 else result.next = new ListNode(l1.val+l2.val); 37 } 38 result = result.next; 39 40 } 41 if(i==count-1&&carry==true) result.next = new ListNode(1); 42 if(l1.next!=null){ 43 l1 = l1.next; 44 l2 = l2.next; 45 } 46 } 47 return head; 48 } 49 50 public int findlength(ListNode l1,ListNode l2){ 51 int result = 1; 52 boolean con = true; 53 while(con){ 54 if(l1!=null&&l1.next!=null) l1 = l1.next; 55 else l1 = null; 56 if(l2!=null&&l2.next!=null) l2 = l2.next; 57 else l2 = null; 58 if(l1==null&&l2==null) con = false; 59 else result++; 60 } 61 System.out.print(result); 62 return result; 63 } 64 65 public void equalboth(ListNode l1,ListNode l2,int count){ 66 for(int i = 0;i<count;i++){ 67 if(l1!=null&&l1.next!=null) l1 = l1.next; 68 else{ 69 ListNode newNode = new ListNode(0); 70 l1.next = newNode; 71 l1 = newNode; 72 } 73 if(l2!=null&&l2.next!=null) l2 = l2.next; 74 else{ 75 ListNode newNode = new ListNode(0); 76 l2.next = newNode; 77 l2 = newNode; 78 } 79 } 80 } 81 }
這裏的兩個方法的作用分別是:
findlength:找到l1和l2中較長的那條鏈,並記錄下鏈的節點數,其實就是找到那個較大數的位數。
equalboth:將節點數較少的那條鏈的位數補全。如56248+235的話,將235補全為00235。
代碼中定義的carry是進位的意思,用於判斷上一次相加是否出現了進位,再根據結果,依次相應位數的數字相加,最終得到結果。這麽做下來中規中矩,沒有什麽兩眼的地方,最後實現的結果也就那樣,60ms的運行時間。
拿出這個方案之後,我想了想,看看還能有什麽更好點的方法,於是又寫了如下的解法:
1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { val = x; } 7 * } 8 */ 9 public class Solution { 10 boolean carry = false; 11 public ListNode addTwoNumbers(ListNode l1, ListNode l2) { 12 ListNode l = null; 13 ListNode head = l; 14 while(l1!=null||l2!=null||carry==true){ 15 if(l==null) { 16 if(l1==null){ 17 head = l2; 18 break; 19 }else if(l2==null){ 20 head = l1; 21 break; 22 } 23 l = new ListNode(addL(l1,l2)); 24 head = l; 25 l1 = l1.next; 26 l2 = l2.next; 27 }else{ 28 l.next = new ListNode(addL(l1, l2)); 29 l = l.next; 30 if(l1!=null) l1 = l1.next; 31 if(l2!=null) l2 = l2.next; 32 } 33 } 34 return head; 35 } 36 37 public int addL(ListNode l1,ListNode l2){ 38 int l = 0; 39 if(l1!=null&&l2!=null){ 40 if(carry==true){ 41 if(l1.val+l2.val>8){ 42 l = l1.val+l2.val-9; 43 carry = true; 44 }else{ 45 l = l1.val+l2.val+1; 46 carry = false; 47 } 48 }else{ 49 if(l1.val+l2.val>9){ 50 l = l1.val+l2.val-10; 51 carry = true; 52 }else{ 53 l = l1.val+l2.val; 54 carry = false; 55 } 56 } 57 }else if(l2==null&&l1!=null){ 58 if(carry ==true){ 59 if(l1.val+1>9){ 60 l = l1.val-9; 61 carry = true; 62 }else{ 63 l = l1.val+1; 64 carry = false; 65 } 66 }else{ 67 l = l1.val; 68 carry = false; 69 } 70 }else if(l1==null&&l2!=null){ 71 if(carry ==true){ 72 if(l2.val+1>9){ 73 l = l2.val-9; 74 carry = true; 75 }else{ 76 l = l2.val+1; 77 carry = false; 78 } 79 }else{ 80 l = l2.val; 81 carry = false; 82 } 83 }else if(l1==null&&l2==null&&carry==true){ 84 l = 1; 85 carry = false; 86 } 87 return l; 88 } 89 }
這個解法中,addL方法只做當前節點的相加,並記錄是否進位,carry是全局變量。這樣便不用考慮兩條鏈的長度,以及不必去補全某條鏈了。
提交之後顯示運行時間是53ms,並沒有得到什麽實質性的提高~水平所限,也只能到這了^_^
我的LC之路-2. Add Two Numbers