Leetcode:剑指Offer027.回文链表(快慢指针)

题目:

给定一个链表的 头节点 head ,请判断其是否为回文链表。

如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。
在这里插入图片描述

解题思想:

1)利用栈的特性。先遍历链表存入栈中,然后比较头节点的值和压栈的值是否一致。(大多数人都能想到)
2)利用快慢指针。快慢指针:准备两个指针,慢指针每次走一下,快指针每次走两下;当快指针遍历完后,慢指针正好到链表的中间。然后后半段链表反转,和头节点比较。

代码1:(栈实现)

public boolean isPalindrome(ListNode head) {
        if(head==null||head.next==null){
            return true;
        }
        ListNode temp=head;
        Stack<Integer> stack=new Stack<Integer>();
        while(temp!=null){
            System.out.println(temp.val);
            stack.push(temp.val);
            temp=temp.next;
        }
        while(stack.size()>0){
            int pop=stack.pop();
            if(pop!=head.val){
                return false;
            }
            head=head.next;
        }
        return true;
    }

(显然这个太Low了)
在这里插入图片描述

代码2:(快慢指针)

public boolean isPalindrome(ListNode head) {
        //讨论0和1的情况
        if (head.next == null || head == null) {
            return true;
        }
        int count = 0;
        ListNode temp1 = head;
        while (temp1 != null) {//判断奇数偶数
            count++;
            temp1 = temp1.next;
        }
        ListNode temp2 = head;
        temp1 = head;
        if ((count + 1) % 2 == 0) {//奇数时候
            while (temp2.next != null) {//快慢指针
                temp1 = temp1.next;
                temp2 = temp2.next.next;
            }
            temp1 = temp1.next;//链表反转
            ListNode help = temp1.next;
            temp2 = temp1;
            temp2.next = null;
            while (help!= null) {
                temp1 = help;
                help = temp1.next;
                temp1.next = temp2;
                temp2 = temp1;
            }
            while (temp1 != null) {//比较
                if (head.val != temp1.val) {
                    return false;
                }
                head = head.next;
                temp1 = temp1.next;
            }
            return true;
        } else if ((count + 1) % 2 != 0) {//偶数时候
            if (temp2.next.next == null) {//2的时候
                if (temp1.val == temp2.next.val) {
                    return true;
                }
                return false;
            } else {//大于2的偶数时候
            	//这里count其实判断奇数偶数的功能已经完成了
            	//但是奇数偶数的快慢指针有细微区别
            	//为了保证快指针到头时候慢指针在中点
            	//先让他们同时都走一步,然后快指针走两步,慢指针走一步
            	//不清楚的可以画画图
                count = 1;
                while (temp2.next != null) {//快慢指针
                    if (count == 1) {
                        temp1 = temp1.next;
                        temp2 = temp2.next;
                        count--;
                    }
                    temp1 = temp1.next;
                    temp2 = temp2.next.next;
                }
                //开始链表反转
                ListNode help = temp1.next;
                temp2 = temp1;
                temp2.next = null;
                while (help!= null) {
                    temp1 = help;
                    help = temp1.next;
                    temp1.next = temp2;
                    temp2 = temp1;
                }
                while (temp2 != null) {//比较
                    if (head.val != temp2.val) {
                        return false;
                    }
                    head = head.next;
                    temp2 = temp2.next;
                }
                return true;
            }
        }
        return false;
    }

在这里插入图片描述

解析:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值