FTPrep, 2 Add Two Numbers
来源:互联网 发布:mysql的insert into 编辑:程序博客网 时间:2024/05/18 22:53
这道题的思路很简单,但是在实现起来还是有点 not intuitive, 参考了一下别人代码,才有感觉:
1,基本思路是:两条链条的同步后移,这个问题就是每个iteration内 用next实现移动就好
2,不断后移的终止条件其实很简单,就是有一方null了,然后就可以考虑直接copy另一条链的剩下值。“不断”两字,可能就是用while() 来实现。
下面的第二段代码其实才是我最初的思路,考虑的角度,找到局部的终止条件,也就是说什么时候可以一条链停止计算,剩下的任务就是copy剩下一条链。
而第一段代码是一个generalized的思路,比较难直接 意识到,因为他是把整个计算结束的终止条件放在while() 里面,也就是考虑各种可以接续下去的情况,但是要注意,如果一条链表的指针已经是null,那就是保持不用变化。这意味着每个case都需要走O(N)。这个思路其实也很不错的,代码非常精简移动。其中while条件的直观说法:只要l1, l2, carry 任何一个适合计算,那就继续计算,产生新ListNode,这里的三目运算符 用得很巧妙,本质上说 三目运算符 就是一些对于二元选择的最适 实现方式。
另外还有一个值得总结的是:凡是+ 运算,基本上都是模块话的东西,sum,digit,carry; 在List的运算中,dummyNode,curr使得操作极为方便
一个非optimal,但是很精简的代码,思路就是遍历,每次的复杂度都是O(N),如果要优化,在判断条件下就要清楚写出来,那么就不用每次都O(N)了,效率会有所提升
以为是效率40%的代码:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */public class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode dummyNode = new ListNode(-1); ListNode curr = dummyNode; int carry = 0; while(l1!=null || l2!=null || carry!=0){ int sum = ((l1!=null)?l1.val:0) + ((l2!=null)?l2.val:0) + carry; int digit = sum%10; carry = sum/10; curr.next = new ListNode(digit); curr = curr.next; l1=(l1!=null)?l1.next:null; l2=(l2!=null)?l2.next:null; } return dummyNode.next; }}
自己知道可以优化的地方是:当一个list计算到头了,其实就可以copy另一个list的剩下的值,copy之前还要判断一下是否carry==1,如果yes,还得把这个carry当作一个list,继续加,如果carry==0,则直接copy该链剩下所有值,这要就不用每个case都计算到O(N)了
以下代码效率80+%
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */public class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode dummyNode = new ListNode(-1); ListNode curr = dummyNode; int carry = 0; int sum = 0; int digit = 0; while(l1!=null && l2!=null){ sum = l1.val + l2.val + carry; digit = sum%10; carry = sum/10; curr.next=new ListNode(digit); curr = curr.next; l1 = l1.next; l2 = l2.next; } while(l1!=null){ if(carry==0){ curr.next=l1; break; } else{ sum = l1.val + 1; digit = sum%10; carry = sum/10; curr.next=new ListNode(digit); curr = curr.next; l1 = l1.next; } } while(l2!=null){ if(carry==0){ curr.next=l2; break; } else{ sum = l2.val + 1; digit = sum%10; carry = sum/10; curr.next=new ListNode(digit); curr = curr.next; l2 = l2.next; } } if(carry==1) curr.next = new ListNode(1); return dummyNode.next; }}
TODO: 尝试用递归的方法来解这道题,无果,有edge case处理不到,就是最后会进位的情况比如2+899。所以要改变ListNode value的问题,用recursion比较难,recursion用在merge 2 sort list,或者是reorder,swap,reverse k-group这些情况会比较无敌,因为没有modify ListNode本身的值。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */public class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { if(l1!=null && l1.val==10){ l1.val=0; if(l1.next==null) l1.next=new ListNode(1); else l1.next.val+=1; return addTwoNumbers(l1,l2); } if(l2!=null &&l2.val==10){ l2.val=0; if(l2.next==null) l2.next=new ListNode(1); else l2.next.val+=1; return addTwoNumbers(l1,l2); } if(l1==null) return l2; if(l2==null) return l1; int val=l1.val+l2.val; l1.val=val%10; int carry=val/10; if(carry>0){ if(l1.next!=null){ l1.next.val+=carry; } else l1.next=new ListNode(carry); } l1.next=addTwoNumbers(l1.next, l2.next); return l1; }}
- FTPrep, 2 Add Two Numbers
- 2 Add Two Numbers
- 2、Add Two Numbers
- 2、Add Two Numbers
- 2 Add Two Numbers
- 2Add Two Numbers
- #2 Add Two Numbers
- 2 - Add Two Numbers
- 2Add Two Numbers
- 2 Add Two Numbers
- 2 Add Two Numbers
- #2 Add Two Numbers
- 2 Add Two Numbers
- Add Two Numbers【2】
- 2、add two numbers
- 2、Add Two Numbers
- 2 - Add Two Numbers
- 2 Add Two Numbers
- 美团编程大赛 数学题 拓展欧几里得和解是否存在
- vuejs路由使用的问题Error in render function: "TypeError: Cannot read property 'matched' of undefined"
- 快递实名制遭遇滑铁卢,背后原因在这里
- 解决Spring+Quartz无法自动注入bean问题
- CentOS 7 开放3306端口访问 iptables
- FTPrep, 2 Add Two Numbers
- 【Leetcode】【python】Arranging Coins
- 初级程序员的业务逻辑简单吗?
- Android MVP模式基类结构
- 编译android 7.0 出现Try increasing heap size with java option '-Xmx<size>'错误解决方案
- Spring容器优雅的关闭
- CodeBlocks 16.01输出中文出错
- codeforces 525E (29/600)
- Communication error with Jack server