题目:回文链表
请判断一个链表是否为回文链表
示例:
输入: 1->2 输出: false
输入: 1->2->2->1 输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
方法一:转成数组
step1:定义一个空数组
step2:遍历链表,将数据存放在数组中
step3:遍历数组,start从前往后,end从后往前,直到start=end结束
step4:如果start对应的数据与end对应的相等,则start往后走,end往前走,否则直接返回false
step5:返回true
时间复杂度O(n),空间复杂度O(n)
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var isPalindrome = function(head) {
//定义一个空数组
const val = []
//将链表数据存入数组中
while(head){
let curr = head.val
val.push(curr)
head = head.next
}
let start = 0
let end = val.length-1
//判断数组中前后数据是否相同
while(start <end){
if(val[start] != val[end]){
return false
}
start++
end--
}
return true
};
方法二:快慢指针
思路:将链表从中间断开,一分为二,然后在对其中一段进行反转,比较
step1:定义一个快指针,一个慢指针
step2:遍历链表,快指针一次走两步,慢指针一次一步,等快指针到末尾,慢指针刚好在中间
step3:断开链表,一分为二
step4:对后半段链表进行反转
step5:遍历两段链表,进行比对
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var isPalindrome = function(head) {
//如果只有一个节点,直接返回true
if(!head || !head.next) return true
//定义快慢指针
let prev = head
let slow = head
let fast = head
//找到中点
while(fast && fast.next){
prev = slow
slow = slow.next
fast = fast.next.next
}
//将链表从中间进行断开
prev.next = null
let head2 = null
//对后半段指针进行反转
while(slow){
let temp = slow.next
slow.next = head2;
head2 = slow;
slow = temp;
}
//对比两段链表对数据
while(head && head2){
if(head.val != head2.val) return false
head = head.next
head2 = head2.next
}
return true
};