简介:今天开始刷LeetCode的算法题,一道题超简单,难度系数为简单。第二道题难度系数是中等。解了两个小时,最终还是参考了社区大佬的解法才做出来。大佬用的词都是简单!!!
题目介绍
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
通过次数498,067 提交次数1,313,877
我的解法
拿到题目就立马开始做了(这个习惯真的不好),题目中并没有说这个链表的长度是多少,给的数据也是给你一种错觉;好像这个数字可以用变量表示。也为我后面的解答错误埋下了伏笔。
第一版的代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode neww(int i,String s,int len,ListNode flage){
String tempstr = s.substring(i,i+1);
int d = Integer.parseInt(tempstr);
ListNode tempd = new ListNode(d);
if(i==len-1){
tempd.next=null;
return tempd;
}else{
tempd.next=neww(i+1,s,len,flage);
if(i==0){
flage = tempd;
}
}
if(i==0){
return flage;
}else{
return tempd;
}
}
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
StringBuilder a = new StringBuilder();
a=a.append(l1.val);
StringBuilder b= new StringBuilder();
b=b.append(l2.val);
ListNode temp1 = l1.next;
ListNode temp2 = l2.next;
while(temp1!=null){
a=a.append(temp1.val);
temp1=temp1.next;
}
while(temp2!=null){
b=b.append(temp2.val);
temp2=temp2.next;
}
Long first = Long.parseLong(a.reverse().toString());
Long second = Long.parseLong(b.reverse().toString());
Long sum = first+second;
String sumStr = (new StringBuilder(sum.toString())).reverse().toString();
int len = sumStr.length();
ListNode flags = null;
flags = neww(0,sumStr,len,flags);
return flags;
}
}
我的思路
于是我想到了,将链表遍历一遍,读成两个数字字符串,因为题目说数字被反转了,于是我想到了可以使用StringBuilder来存储,最后一个reverse()方法就可以实现反转,多方便!
很久没有做算法题了,有的生疏,没想到可以用傀儡对象来实现链表的传递生成,于是用了最笨的递归方法,写的头都要炸了。特别是leetcode没有解释执行提醒你。头大!!!
bug出现
不过总算写完了,而且稍微测了一下,还是可以正确执行的。于是我点击了提交,然后,就报错了。
Line 47: java.lang.NumberFormatException:
For input string: "9999999991"
检查之后发现系统给的测试数据,给了个9999999991,这个字符串转化为int时会产生溢出,这样这个方法行不通了。
抢救失败
感觉还能抢救一下,都写了这么久这么多代码了,不能狗带。
于是我改为用long来接受吧,希望能成功吧。
很遗憾,又一次提交之后报错了;
Line 46: java.lang.NumberFormatException:
For input string: "1000000000000000000000000000001"
这一次系统测试的数据已经把long撑爆了。
好吧,你看我还有机会吗?
参考优秀解答
清晰的思路
阅读了一个网友的解答,经过他的解释,瞬间恍然大悟。
既然题目时逆序,必然不是故意刁难,而是方便读者解答,
其实是给我们降低难度而不是提升难度。
逆序就代表数字的高低位是相反的,这个很符合我们从各位开始相加不断进位的过程。
再加上傀儡对象的存在,可以不参用递归生成链表了。瞬间大梦初醒,哭晕在厕所,竟然把一血献给了这个小学生都会做的题目。
第二版的代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int sum = l1.val+l2.val;
int plus = sum>9?1:0;
ListNode res = new ListNode(sum%10);
ListNode temp = res;
ListNode b1 = l1.next;
ListNode b2 = l2.next;
while(b1!=null||b2!=null||plus==1){
int sumt = (b1!=null?b1.val:0)+(b2!=null?b2.val:0)+plus;
plus=sumt>9?1:0;
temp.next = new ListNode(sumt%10);
temp=temp.next;
if(b1!=null){
b1=b1.next;
}
if(b2!=null){
b2=b2.next;
}
}
return res;
}
}
中途出现了一个小bug,不过很快解决了。总算是成功了。
我的收获
一、拿到题目一定要分析清楚,不要省那几分钟,如果没考虑清除,后面走错路花费掉的时间就等于打水漂,这个是没有什么过程分的。
二、尽量顺着已知的条件来,有时候出题者并不是想刁难你,而是想让方便解答。
三、尽量少依赖各种包装类以及类库方法,因为没有解释执行来提醒你哪里写错有语法错误了,如果你记忆力不好真的很容易满屏的bug。
四、尽量用算法的简洁思想去解决,简化数据操作的步骤。
备注
友情链接:leetcode在线