LeetCode偶尔一题 —— 234. 回文链表

原文地址:https://juejin.im/post/6887059077025939469
原题地址:https://leetcode-cn.com/problems/palindrome-linked-list/

题目描述

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

示例 1:

输入: 1->2
输出: false

示例 2:

输入: 1->2->2->1
输出: true

进阶:
你能否用 \(O(n)\) 时间复杂度和 \(O(1)\) 空间复杂度解决此题?

解题思路

思考一个点,如果要用 \(O(1)\) 时间复杂度来解决的话,说明要利用链表本身来解决这个问题。想通这点,下面的思路就能顺其自然的想出来了👇

  1. 将一条链表切分成两条对称的链表
    • 获取链表的中间节点以及它的节点数量
    • 如果节点数量是奇数,那么可以舍去中间节点并借此分割链表,否则将中间节点分配给左侧的链表
  2. 反转其中一条链表
  3. 对比两条链表的值

代码

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {boolean}
 */
const isPalindrome = function(head) {

    /**
     * 切分链表
     * @param head {ListNode}
     * @return {ListNode}
     */
    const splitLinkList = (head) => {
        let prev = null
        let low = head
        let fast = low.next
        let nextHead = null
        let cnt = 1
        while (fast && fast.next) {
            prev = low
            low = low.next
            fast = fast.next.next
            cnt++
        }
        cnt = cnt * 2 - (fast ? 0 : 1)
        nextHead = low.next
        low.next = null
        if (cnt % 2 === 1) {
            prev.next = null
        }
        return nextHead
    }

    /**
     * 反转链表
     * @param head {ListNode}
     * @return {void}
     */
    const reverseLinkList = (head) => {
        if (!head) {
            return null
        }
        let prev = head
        let next = head.next
        while (next) {
            head.next = next.next
            next.next = prev
            prev = next
            next = head.next
        }
        return prev
    }

    /**
     * 检查链表是否相同
     * @param head {ListNode}
     * @param nextHead {ListNode}
     * @return {boolean}
     */
    const checkLinkList = (head, nextHead) => {
        if (!head && !nextHead) {
            return true
        }
        if (!head || !nextHead || head.val !== nextHead.val) {
            return false
        }
        return checkLinkList(head.next, nextHead.next)
    }

    if (!head || !head.next) {
        return true
    }
    const nextHead = splitList(head)
    head = reverseLinkList(head)
    return checkLinkList(head, nextHead)
};
posted @ 2020-10-24 13:49  pigpigever  阅读(69)  评论(0编辑  收藏  举报