给你一个单链表的头节点 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
};