法一:转数组后遍历
将链表转化成数组后遍历判断,此时遍历只需要遍历数组的前半部分,或者使用双指针法,代码如下:
时间复杂度:O(n),空间复杂度O(n)
/**
* 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 curr = head, arr = [];
while (curr) {
arr.push(curr.val);
curr = curr.next;
}
for (let i = 0; i < Math.floor(arr.length / 2); i++) {
if (arr[i] !== arr[arr.length - 1 - i]) {
return false;
}
}
//或者
// for (let i = 0, j = arr.length - 1; i < j; ++i, --j) {
// if (arr[i] !== arr[j]) {
// return false;
// }
// }
return true;
};
法二: 转数组后反转判断
将链表转化成数组,然后将数组转成字符串与逆序后字符串比较,相等则是回文,代码如下:
/**
* 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 curr = head, arr = [];
while (curr) {
arr.push(curr.val);
curr = curr.next;
}
return arr.join('') === arr.reverse().join('');
};
法三:反转一半链表
将前一半链表反转与后一半链表依次比较,步骤如下:
1、求出链表长度
2、反转后半部分链表
3、判断是否回文
4、恢复链表
代码如下:
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
const endOfFirstHalf = (head, len) => {
let mid = Math.ceil(len / 2);
let cur = head;
while (mid--) {
cur = cur.next;
}
return cur;
}
const reverseList = (head) => {
let cur = head;
let pre = null;
while (cur) {
let nextTemp = cur.next;
cur.next = pre;
pre = cur;
cur = nextTemp;
}
return pre;
}
var isPalindrome = function(head) {
if (!head) {
return true;
}
let cur = head;
let len = 0;
while (cur) {
len++;
cur = cur.next;
}
if (len === 1) {
return true;
}
// 找到后半部分的头节点
const firstHalfEnd = endOfFirstHalf(head, len);
// 反转链表后半部分
const secondHalfStart = reverseList(firstHalfEnd);
// 判断是否回文
let p1 = head;
let p2 = secondHalfStart;
let result = true;
while (result && p2) {
if (p1.val != p2.val) result = false;
p1 = p1.next;
p2 = p2.next;
}
// 还原链表并返回结果
firstHalfEnd.next = reverseList(secondHalfStart);
return result;
};