跳到主要内容

234. 回文链表

easy

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false

image-20220808114349967

快慢指针 + 反转

利用快慢指针将链表分割成前后两部分,然后反转后半部分链表,就可以一一比较了

package linked_list

func isPalindrome(head *ListNode) bool {
if head == nil {
return true
}
slow, fast := head, head
for fast.Next != nil && fast.Next.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
// slow 即为前半部分的尾节点,如果链表为奇数,那么slow为中间节点

startOfSecondHalf := reverseList(slow.Next) // 后半部分的头节点 顺便反转一下后半部分

p, q := head, startOfSecondHalf
for q != nil {
if p.Val != q.Val {
return false
}
p, q = p.Next, q.Next
}
return true

}

func reverseList(head *ListNode) *ListNode {
if head == nil {
return nil
}
var pre, cur *ListNode = nil, head
for cur != nil {
tmp := cur.Next
cur.Next = pre
pre, cur = cur, tmp
}
return pre
}

时间复杂度:O(n),其中 n 指的是链表的大小。

空间复杂度:O(1),我们只会修改原本链表中节点的指向,而在堆栈上的堆栈帧不超过 O(1)