方法一:利用数组(栈)
遍历链表,用数组把数据存下来,然后再进行一次遍历,同时用数组反向地与之比较,这样就可以判断是否回文。这个方法时间复杂度是O(n)
- pop() 移除数组的最后一项,返回移除的项
- shift() 移除数组的第一项,返回移除项
var isPalindrome = function (head) {
let nums = [];
while (head) {
nums.push(head.val);
head = head.next;
}
while (nums.length > 1) { //注意是大于1
if (nums.pop() != nums.shift())
return false;
}
return true;
};
方法二:快慢指针(双指针)
时间复杂度O(n) 空间复杂度O(1)
思路:利用快慢指针p和q,初始时均指向头结点。之后慢指针q每走一步,快指针走两步。当快指针走到链表的尾部时,慢指针所指向的结点即为中间结点。这时等于把链表劈成了两半,然后把后半部分链表逆置,最后依次比较前半部分链表和逆置后的链表即可。
示意图
原始输入如下
我们调整链表之后
从head1与head2处开始遍历,如果在遍历的过程中发现不一致情况,直接返回false,如果直到有任意一方为空都没有不一致现象,那么就返回true。
最后记得调整回去。
var isPalindrome2 = function(head) {
let slow = head, fast = head;
while(fast && fast.next){
slow = slow.next;
fast = fast.next.next;
}
//反转后半段,这里跟之前反转链表的题一样,得到的
let reverse = null;
while(slow !== null){
let tmp = slow.next;
slow.next = reverse;
reverse = slow;
slow = tmp;
} //到这里,reverse就是反转好的后半部分链表
// 将反转好的链表和原链表的前半部分依次进行值的比较
while(reverse !== null){
if(reverse.val !== head.val)
return false;
reverse = reverse.next;
head = head.next;
}
return true;
};