如果有其他更好的方法,欢迎在评论区留言~
题目描述
给定一个链表,请判断该链表是否为回文结构。
回文是指该字符串正序逆序完全一致。
数据范围: 链表节点数0≤n≤105,链表中每个节点的值满足 ∣val∣≤107
知识点
链表、双指针
示例
输入:
{1}
返回值:
true
输入:
{2,1}
返回值:
false
说明:2->1
输入:
{1,2,2,1}
返回值:
true
说明:1->2->2->1
解题过程
方法一:数组反转
具体做法:
- 遍历一次链表,将元素取出放入辅助数组中。
- 准备另一个辅助数组,录入第一个数组的全部元素,再将其反转。
- 依次遍历原数组与反转后的数组,若是元素都相等则是回文结构,只要遇到一个不同的就不是回文结构
/*
* function ListNode(x){
* this.val = x;
* this.next = null;
* }
*/
/**
*
* @param head ListNode类 the head
* @return bool布尔型
*/
function isPail( head ) {
// write code here
var array=[],res=[];
while(head){
array.push(head.val);
res.push(head.val);
head=head.next;
}
res.reverse();
for(var i=0;i<array.length;i++){
if(res[i]!=array[i]){
return false;
}
}
return true;
}
module.exports = {
isPail : isPail
};
复杂度分析
- 时间复杂度:O(n),其中n为链表的长度,遍历链表转化数组为O(n),反转数组为O(n),后续遍历两个数组为O(n)
- 空间复杂度:O(n),记录链表元素的辅助数组,及记录反转后数组
方法二:双指针
具体做法:
- 遍历一次链表,将元素取出放入辅助数组中。
- 使用下标访问,i、j 分别从数组首和尾开始遍历,i 从左到右,j 从右到左,依次比较元素是否相同。
- 如果有不一样,则不是回文结构。否则遍历到 i 和 j 相遇就行了。
/*
* function ListNode(x){
* this.val = x;
* this.next = null;
* }
*/
/**
*
* @param head ListNode类 the head
* @return bool布尔型
*/
function isPail( head ) {
// write code here
var array=[];
while(head){
array.push(head.val);
head=head.next;
}
for(var i=0,j=array.length-1;i<j;i++,j--){
if(array[i]!=array[j]){
return false;
}
}
return true;
}
module.exports = {
isPail : isPail
};
复杂度分析
- 时间复杂度:O(n),其中n为链表的长度,遍历链表转化数组为O(n),双指针遍历半个数组为O(n)
- 空间复杂度:O(n),记录链表元素的辅助数组
方法三:栈逆序
具体做法:
- 遍历链表,将链表元素依次加入栈中。
- 依次从栈中弹出值,和链表的顺序遍历比较,如果一一比较都是相同的值,那正好就是回文,否则就不是。
/*
* function ListNode(x){
* this.val = x;
* this.next = null;
* }
*/
/**
*
* @param head ListNode类 the head
* @return bool布尔型
*/
function isPail( head ) {
// write code here
var array=[],res=head;
while(head){
array.push(head.val);
head=head.next;
}
while(array.length!=0){ //正序遍历链表,从栈中弹出的内容是逆序的
if(array.pop()!=res.val){
return false;
}
res=res.next;
}
return true;
}
module.exports = {
isPail : isPail
};
复杂度分析
- 时间复杂度:O(n),其中n为链表的长度,遍历链表入栈为O(n),后续再次遍历链表和栈
- 空间复杂度:O(n),记录链表元素的辅助栈长度和链表相同