234. Palindrome Linked List(判断回文链表)

231 阅读1分钟

Desc

Given a singly linked list, determine if it is a palindrome.

Example 1:

Input: 1->2
Output: false

Example 2:

Input: 1->2->2->1
Output: true

Follow up: Could you do it in O(n) time and O(1) space?

描述

判断回文链表 O(n) O(1)

思路

快慢指针找中间节点

比如1 2 3 slow—>2

反转后:
1 2 null
3 2 null
注意1依然指向2(便于最后恢复),没有做切断,但2已经指向null

比如1 2 3 4 slow->3

反转后:
1 2 null
4 3 null
注意2依然指向3(便于最后恢复),没有做切断),但3已经指向null

 /**
     * 快慢指针
     * @param head
     * @return
     */
    public boolean isPalindrome(ListNode head) {
        // 通常需要考虑的因素是0和1的情况
        if(head == null || head.next == null){
            return  true;
        }
        ListNode fast = head;
        ListNode slow = head;

        // 寻找中间节点
        // 1-2 slow=2 fast=null
        // 1-2-3 slow=2 fast=3
        // 1-2-3-4 slow=3 fast=null
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }


        // 倒转中间后边的链表 但是没有切断前面的指向
        slow = reverseLinkedList(slow);
        // 最后要恢复
        ListNode save = slow;

        fast = head;
        boolean res = true;

        while (slow != null) {
            if (slow.val != fast.val) {
                res = false;
                break;
            }
            slow = slow.next;
            fast = fast.next;
        }
        reverseLinkedList(save);
        return res;


    }

    private ListNode reverseLinkedList(ListNode head) {
        ListNode pre = null;
        ListNode next;
        while (head != null) {
            next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }