回文链表 使用额外空间的方法与空间复杂度为1的方法

题目描述:

给定一个链表的 头节点 head ,请判断其是否为回文链表。
如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。

方法一:

思路: 首先使用快慢指针找到链表中间的节点,之后从中间节点开始依次压栈,直到末尾。最后将栈中的每一个元素弹出和正向遍历链表的元素比较看是否相等,若有一个不相等,则直接返回false。


class Solution {

    public boolean isPalindrome(ListNode head) {
        
        if (head == null || head.next == null) {
            return true;
        } 

        ListNode pre = head;
        ListNode last = head;

        Stack<ListNode> stack = new Stack<>();

        while (last.next != null && last.next.next != null) {
            pre = pre.next;
            last = last.next.next;
        }

        pre = pre.next;

        while (pre != null) {
            stack.push(pre);
            pre = pre.next;
        }

        pre = head;
        while (!stack.isEmpty()) {

            ListNode node = stack.pop();
            if (pre.val != node.val) {
                return false;
            }

            pre = pre.next;
        } 
        
        return true;
    }

}

方法二:

思路: 使用快慢指针,在快指针走完时满指针会走到中间的位置,之后,从慢指针只想中间节点的位置开始将链表剩余的部分反转。比较晚每个元素之后再将反转的链表恢复。


class Solution {

    public boolean isPalindrome(ListNode head) {
        
        if (head == null || head.next == null) {
            return true;
        }
                
        // 找到中间节点
        ListNode pre = head;
        ListNode last = head;
        while (last.next != null && last.next.next != null) {
            pre = pre.next;
            last = last.next.next;
        }

        // 从中间节点以后讲链表逆序
        last = pre.next;
        pre.next = null;
        ListNode temp = null;
        while (last != null) {
            temp = last.next;
            last.next = pre;
            pre = last;
            last = temp;
        }

        // 此时pre指向原来链表的最后一个节点, 使用temp保留
        temp = pre;
        last = head;

        while (pre != null && last != null) {
            if (pre.val != last.val) {
                return false;
            }
            pre = pre.next;
            last = last.next;
        }

        // 恢复原来的链表
        pre = temp;
        temp = null;
        while (pre != null) {
            last = pre.next;
            pre.next = temp;
            temp = pre;
            pre = last;
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值