写在前面:在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,并没有得到什么实质性的提高~水平所限,也只能到这了^_^