LeetBook——链表——回文链表

回文链表

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false
示例 2:

输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

解法

  • 找到链表中间节点,快指针法

  • 将后半部分链表逆转

  • 比较前半部分链表和后半部分链表

  • 再次逆置后半部分链表,修复链表,逆置链表直接用的以前写过的题的代码

  • 时间复杂度:逆置两次后半部分的表(n),寻找中间节点需要遍历整个表一次,比对节点 也需要遍历表(n / 2)。

在这里插入图片描述

public boolean isPalindrome(ListNode head) {

        if( head == null || head.next == null ) //如果表为空,或表中只有一个元素,直接返回原表
            return true;

        ListNode halfHead = head;       //遍历前半表的工作指针
        ListNode half = getHalf(head);  //找到中间节点
        half = reverseList(half.next);  //逆置后半部分链表
        ListNode tag = half;            //记录中间节点

        while ( half !=null){
            if(half.val != halfHead.val){   //如果有不同的,说明不是回文链表,修复链表,返回false

                reverseList(tag.next);
                return false;
            }else {
                half = half.next;
                halfHead = halfHead.next;
            }
        }

        reverseList(tag.next);      //比对完了,说明是回文链表,修复链表,返回true
        return true;
    }

    private ListNode getHalf(ListNode head){    // 寻找中间节点   时间复杂度 O(n)
        ListNode faster = head;
        ListNode slower = head;

        while ( faster.next != null && faster.next.next != null){
            slower = slower.next;
            faster = faster.next.next;
        }

        return slower;

    }


    private ListNode reverseList(ListNode head) {   //逆置链表  时间复杂度O(n)

        if( head == null || head.next == null ) //如果表为空,或表中只有一个元素,直接返回原表
            return head;

        ListNode workPointer = head.next;       //workPoint是工作指针,tag用来保存链表还没处理的部分
        head.next = null;                       //将第一个元素摘下,看作一个只有一个元素的链表
        ListNode tag;
        while (workPointer != null){            //workPoint与tag协作,将链表中还未处理完的部分一个一个的头插到head,并将head指针指向刚插入的元素
                                                //指针,指引用
            tag = workPointer.next;
            workPointer.next = head;
            head= workPointer;
            workPointer = tag;
        }
        return head;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值