Leetbook作业记录:回文链表

作业感受

题目地址:https://leetcode-cn.com/leetbook/read/linked-list/fov6t/

其实这道题对我来说有些难的感觉,因为一开始就想着回文链表必须是偶数个,结果提交以后发现有错,回头才测试[1]这个用例,结果是true啊,血的教训啊,呜呜呜~~~

于是开始考虑奇数个元素和偶数个元素两种情况。

我的思路是这样的:
1)先遍历链表的所有元素,拿到元素的个数;
2)如果是偶数,快速判断2个元素的特殊情况,然后采取反转前半段链表,再逐一对比前一半和后一半的元素是否逐一相等,如果是返回true,否则返回false;
3)如果是奇数,快速判断3个元素的特殊情况,然后采取反转前半段链表,再逐一对比前一半和后一半的元素是否逐一相等,如果是返回true,否则返回false.

这么想之后,提交了两次,却还是有问题。然而在leetcode上面也不方便debug,于是我决定查找官方题解。

官方给出了两种方法,1)将链表改为数组,然后用下标遍历比较;
2)用递归算法迭代比较。

看了官方给的代码,Java的代码果然还是更冗长啊,不过还是想要把java重新学一下,正好结合设计模式的内容一起。不把双手插进土地,怎么能种植自己的庄稼呢?

看了官方的代码,其实觉得有一个地方有疑问,就是在使用List的时候觉得还是有些不谨慎,题目给了val的区间是【1,9】,但是也没有说都是整数啊,这个结构可能会出现问题吧,内心有一丝不安,我的话就用arrayList好啦。

反省一下自己,明明感觉到链表前后退很不方便,也没有考虑改变数据结构,思维还是有些僵化了。恩,继续努力。感觉多年不写代码还是自己太懒的缘故,不能简单归咎到工作性质。感谢leetcode这个平台,给了我这么多好的练习题。终于又找回上学时的探索乐趣啦。

也记录一下错题的代码,真的是思路很纠结啦。

错题代码

class Solution {
    public boolean isPalindrome(ListNode head) {

        if( head == null ) return false;
        if( head.next == null) return true;

        ListNode fast = head, slow, middle; 
        int count = 0,sz =0;

        while(fast != null){
            sz++;
            fast = fast.next;
        }
        
       // 如果链表长度为偶数
        if(sz%2 == 0){ 
            fast = head;   
            if(sz == 2){
                if(fast.val == fast.next.val) return true;
                else return false;
            }    
            
            // fast找到链表的中点右边的节点
            while(count != sz/2){
                count++;
                fast = fast.next;
            }


            middle = fast;
            slow = head;
            fast = head;

           //反转前半部分链表
            while(fast != middle  && slow.next != middle){
                fast = fast.next;
                slow.next = fast.next;
                head.next = new ListNode(fast.val, head);
            }
            
            // 对比反转后的前半部分链表和后半部分是否逐一相等,是则返回true,否则返回false
            slow = head;
            fast = middle;
            while(slow.val == fast.val){
                slow = slow.next;
                fast = fast.next;
                if(slow.val != fast.val) return false;
                if(fast == null) return true;   
            }
            

        }else{
            fast = head;   
            if(sz == 3){
                if(fast.val == fast.next.next.val) return true;
                else return false;
            }    
            
            //fast找到链表的中点
            while(count != (sz-1)/2){
                count++;
                fast = fast.next;
            }


            middle = fast;
            slow = head;
            fast = head;

           //反转前半部分链表
            while( slow.next != middle && fast != middle){
                fast = fast.next;
                if(fast == middle) break;
                slow.next = fast.next;
                head.next = new ListNode(fast.val, head);
            }
         
            // 对比反转后的前半部分链表和后半部分是否逐一相等,是则返回true,否则返回false
            slow = head;
            fast = middle.next;
            while(slow.val == fast.val && fast != null){
                slow = slow.next;
                fast = fast.next;
                if(slow.val != fast.val) return false;
                if(fast == null) return true;          
            }           
        }
        return false;
    }
}

改错代码

很认可官方给出的第一种思路,就采用啦。第二中递归的思路我觉得理解起来有些困难,这个涉及到递归的逆序打印问题,目前我的状态还不是很适合这种递归,我决定只跟一种官方思路啦。

class Solution {
    public boolean isPalindrome(ListNode head) {

        if(head == null) return false;

        List vals = new ArrayList();
        ListNode curr = head;

        for(int i = 0; curr != null; i++){
            vals.add( curr.val );
            curr = curr.next;
        }

        int n = vals.size();

        int front=0, back = n-1;

        while(front < back){

            if(!vals.get(front).equals(vals.get(back))) return false;
            front++;
            back--;
        }
        return true;

    }
}

改错代码表现

在这里插入图片描述

总体表现很差啊。

不过我发现这个统计结果也不稳定,上一次我把同样的代码在不同时间提交了,结果差了1ms, 但是那道题原来就是0ms,大家都是0ms,结果虽然差了1ms,但是百分比是相差100%的。理论和实践的距离啊,总是那么扑朔迷离~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不争之德

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值