[LeetCode] 234. Palindrome Linked List

Given the head of a singly linked list, return true if it is a palindrome or false otherwise.

Example 1:
Example 1
Input: head = [1,2,2,1]
Output: true

Example 2:
Example 2
Input: head = [1,2]
Output: false

Constraints:
The number of nodes in the list is in the range [1, 105].
0 <= Node.val <= 9

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

回文链表。

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

思路

题意是给一个链表,判断是不是回文链表。思路是快慢指针找到链表中点,reverse 后半段,然后比较前半和后半。题目要求不能使用额外空间。

注意代码中找中点的部分,slow 指针需要停在前半部分的最后一个节点。这个细节容易错。

复杂度

时间O(n) - 题目要求
空间O(1) - 题目要求

代码

Java实现

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        // corner case
        if (head == null) {
            return true;
        }
        // normal case
        ListNode middle = findMiddle(head);
        middle.next = reverse(middle.next);
        ListNode p1 = head;
        ListNode p2 = middle.next;
        while (p1 != null && p2 != null) {
            if (p1.val != p2.val) {
                return false;
            }
            p1 = p1.next;
            p2 = p2.next;
        }
        return true;
    }

    // 注意这里找中点的写法,middle会停在左半边的最后一个节点
    private ListNode findMiddle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }

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

JavaScript实现

/**
 * @param {ListNode} head
 * @return {boolean}
 */
var isPalindrome = function(head) {
    if (head === null) return true;
    let middle = findMiddle(head);
    middle.next = reverse(middle.next);

    let p = head;
    let q = middle.next;
    while (p !== null && q !== null) {
        if (p.val !== q.val) {
            return false;
        }
        p = p.next;
        q = q.next;
    }
    return true;
};

var findMiddle = function(head) {
    let slow = head;
    let fast = head.next;
    while (fast !== null && fast.next !== null) {
        slow = slow.next;
        fast = fast.next.next;
    }
    return slow;
}

var reverse = function(head) {
    let pre = null;
    while (head !== null) {
        let next = head.next;
        head.next = pre;
        pre = head;
        head = next;
    }
    return pre;
}

相关题目

125. Valid Palindrome
234. Palindrome Linked List
680. Valid Palindrome II
2130. Maximum Twin Sum of a Linked List
posted @ 2019-11-10 09:28  CNoodle  阅读(204)  评论(0)    收藏  举报