面试题:判断一个链表是否为回文结构

面试题:判断一个链表是否为回文结构

面试题:判断一个链表是否为回文结构

这道题,因为需要遍历链表,所以时间复杂度肯定是O(n)的。如果使用空间复杂度为O(n)是非常简单的,无非是遍历一遍链表,将节点保存到数组、List或者栈中,然后判断一次是否回文。但是如何使用常数阶的空间复杂度呢?

public class NC96 {

    /**
     * 解题思路:
     * 这道题目可以将链表中的数值遍历一遍保存到数组中,这样判断回文串是非常的简单的,但是这样操作的空间复杂度是O(n),我觉得应该
     * 有其他的优化方式。
     *
     * 使用快慢指针,快指针的速度是慢指针的两倍,快指针到达链表末尾时,慢指针就是中间位置。
     * 将慢指针后面的链表改变方向,并使用链表后半部分跟链表的前半部分对比,如果相同,则是回文,否则不是回文。
     * 记着后面还要将链表把方向改回来。
     *
     * @author freedom wang
     * @date 2021-02-06 16:47:33
     */
    public boolean isPail(ListNode head) {
        // 特殊情况判断
        if (head == null || head.next == null) {
            return true;
        }

        // 1. 定义快慢指针,快指针速度为慢指针的两倍,快指针到达末尾,则慢指针为中间
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode slow = dummy;
        ListNode fast = dummy;
        while (fast.next != null) {
            fast = fast.next;

            if (fast.next != null) {
                fast = fast.next;
            }

            slow = slow.next;
        }

        // 2. 从慢指针开始反转链表
        ListNode reverse = reverse(slow);

        // 3. 判断是否回文
        boolean isPail = true;
        ListNode head1 = head;
        ListNode head2 = reverse;
        while (head1 != slow && head2 != slow) {
            if (head1.val != head2.val) {
                isPail = false;
                break;
            } else {
                head1 = head1.next;
                head2 = head2.next;
            }
        }

        // 4.将链表反转回去
        reverse(reverse);

        return isPail;
    }

    private ListNode reverse(ListNode node) {
        if (node == null || node.next == null) {
            return node;
        }

        ListNode pre = null;
        ListNode cur = node;

        while (cur != null) {
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }

        return pre;
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值