题目
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。link
示例 1:
输入: head = [1,2,2,1]
输出: true
示例 2:
输入: head = [1,2]
输出: false
思路
- 解法1: 快慢指针
- 快指针每次比慢指针都多走一步,快指针走到最后的时候,慢指针走到链表中间的点
- 然后反转部分后半部分链表
- 将反转后的链表和前半部分链表进行比较。
这里注意的是奇偶个数对中间节点的影响,如果是偶数个点,则slow正好走到后半部分第一个节点,如果是奇数个点,则slow正好走到中间节点,需要往后走一步,跳过中间节点。然后再进行反转。
var isPalindrome = function(head) {
let fast = head;
let slow = head;
while (fast && fast.next) {
fast = fast.next.next;
slow = slow.next;
}
// 如果是奇数个点,则slow是指向中间的点,需要往后走一步
if (fast) {
slow = slow.next;
}
slow = reverseList(slow);
fast = head;
while (slow) {
if (slow.val !== fast.val) {
return false;
}
fast = fast.next;
slow = slow.next;
}
return true;
};
- 解法2: 递归解法,类似递归算法访问链表,先走到链表最后一个元素,然后判断第一个节点和最后一个节点的值是否相等,如果相等,则本次递归返回true,并且第一个节点也向后走一步,否则返回false
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
let firstNode;
const check = function(head) {
// 走到最后一个节点
if (!head) {
return true
}
const res = check(head.next)
// 如果返回true,则进行当前节点和前面节点的值,相等的话返回true
if (res && firstNode.val === head.val) {
firstNode = firstNode.next;
return true;
}
return false;
}
/**
* @param {ListNode} head
* @return {boolean}
*/
var isPalindrome = function(head) {
firstNode = head;
return check(head);
};