解法一:将所有入栈比对
将所有值入栈,然后出栈进行比对,不相等返回false,相等返回true
- ts
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
function isPalindrome(head: ListNode | null): boolean {
let stack = []
let cur = head
while (cur) {
stack.push(cur)
cur = cur.next
}
while (head) {
if (head.val != stack.pop().val) return false
head = head.next
}
return true
};
- 时间复杂度 O ( n ) O(n) O(n)
- 空间复杂度 O ( n ) O(n) O(n)
解法二:快慢指针+栈
首先取到中间元素(快指针两步慢指针一步,快指针跑完,慢指针就在中间)
然后将后半部分入栈
然后出栈比较,直到栈为空
- ts
function isPalindrome(head: ListNode | null): boolean {
if (!head || !head.next) return true
let right = head.next as ListNode
let cur = head
while (cur.next && cur.next.next) {
right = right.next
cur = cur.next.next
}
let stack = []
while(right){
stack.push(right)
right = right.next
}
while(stack.length){
if(stack.pop().val!=head.val)return false
head = head.next
}
return true
}
- 时间复杂度 O ( l o g N ) O(logN) O(logN)
- 空间复杂度 O ( l o g N ) O(logN) O(logN)
解法三:快慢指针
首先取到中间元素(快指针两步慢指针一步,快指针跑完,慢指针就在中间)
然后将后半部分逆序
将逆序后的部分依次与开头比较是否相等,对比结束后记录最终状态
将右半部逆序回来
function isPalindrome(head: ListNode | null): boolean {
if (!head || !head.next) return true
let n1 = head
let n2 = head
while (n2.next && n2.next.next) {
n1 = n1.next
n2 = n2.next.next
}
n2 = n1.next
n1.next = null
let n3: ListNode | null = null
while (n2) {
n3 = n2.next
n2.next = n1
n1 = n2
n2 = n3
}
n3 = n1
n2 = head
let res = true
while (n1 && n2) {
if (n1.val != n2.val) res = false
n1 = n1.next
n2 = n2.next
}
n1 = n3.next
n3.next = null
while (n1) {
n2 = n1.next
n1.next = n3
n3 = n1
n1 = n2
}
return res
}
- 时间复杂度 O ( l o g N ) O(logN) O(logN)
- 空间复杂度 O ( 1 ) O(1) O(1)