LCR 027.回文链表
给定一个链表的 头节点 head
**,**请判断其是否为回文链表。
如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。
示例 1:
输入: head = [1,2,3,3,2,1]
输出: true
示例 2:
输入: head = [1,2]
输出: false
提示:
- 链表 L 的长度范围为
[1, 105]
0 <= node.val <= 9
法1:数组
分析:
如果只有一个结点,直接返回true。
其他情况,遍历结点,将值存入数组,然后判断是否是回文。
时间复杂度 : O ( n ) O(n) O(n)
空间复杂度 : O ( n ) O(n) O(n)
js
var isPalindrome = function(head) {
if(head !== null && head.next === null) return true;
let arr = [];
let cur = head;
while(cur !== null){
arr.push(cur.val);
cur = cur.next;
}
let left = 0;
let right = arr.length - 1;
while(left < right){
if(arr[left] !== arr[right]){
return false;
}
left++;
right--;
}
return true;
};
法2:快慢指针
分析:
看例子 head = [1,2,3,3,2,1]
时间复杂度 : O ( n ) O(n) O(n)
空间复杂度 : O ( 1 ) O(1) O(1)
js
var isPalindrome = function(head) {
// 如果链表为空或只有一个节点,是回文
if (!head || !head.next) return true;
// 快慢指针找到链表的中间节点
let slow = head;
let fast = head;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
}
// 反转后半部分链表
let prev = null;
while (slow) {
let next = slow.next;
slow.next = prev;
prev = slow;
slow = next;
}
// 比较前半部分和后半部分是否相等
let left = head;
let right = prev; // prev 是反转后的链表头
while (right) { // 只需遍历后半部分
if (left.val !== right.val) {
return false;
}
left = left.next;
right = right.next;
}
return true;
};