234. 回文链表

52 阅读1分钟

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

示例 1:

输入: head = [1,2,2,1]
输出: true

示例 2:

输入: head = [1,2]
输出: false

题解 :

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {boolean}
 */
var isPalindrome = function (head) {
    // 方法一:链表转为数组,然后进行头尾对比
    let arr = []
    // 遍历链表生成数组
    while (head != null) {
        arr.push(head.val)
        head = head.next
    }
    // 循环数组判断
    for (let i = 0, j = arr.length - 1; i < j; i++, j--) {
        if (arr[i] != arr[j]) return false
    }
    return true
    // 方法二:双向链表
    // s=>缓存当前指针,newHead=>新的对比头节点
    // 偶数           1 ---> 2 ---> 2 ---> 1 ---> null
    // 第一轮: n <-- q、n   s      f  
    // 第二轮:        n <-- q、n   s               f

    // 奇数           1 ---> 2 ---> 3 ---> 2 ---> 1 ---> null
    // 第一轮: n < --q、n   s      f
    // 第二轮:        n < --q、n   s              f
    let q, n;
    let s = head, f = head; // s=>慢指针  f=>快指针

    while (f && f.next) {
        q = s // 记录节点
        s = s.next;
        f = f.next.next;
        q.next = n; // 翻转节点
        n = q // 节点赋值
    }
    // 奇数链表时 f=>快指针指向最后一个元素 此时s=>慢指针后移一位
    if (f) {
        s = s.next
    }
    while (s && n) {
        if (s.val !== n.val) {
            return false
        }
        s = s.next;
        n = n.next
    }
    return true
};