【好难】我在LeetCode刷第二道题时献上了一血

简介:今天开始刷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在线

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr. 良爷

您每一分的打赏都是对原创的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值