/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */

func isPalindrome(head *ListNode) bool {
    if head == nil || head.Next == nil {
        return true
    }
    
    // 找到链表的中点
    slow, fast := head, head
    for fast.Next != nil && fast.Next.Next != nil {
        slow = slow.Next
        fast = fast.Next.Next
    }
    
    // 反转后半部分链表
    secondHalf := reverseList(slow.Next)
    
    // 比较前半部分和反转后的后半部分链表
    p1, p2 := head, secondHalf
    for p2 != nil {
        if p1.Val != p2.Val {
            return false
        }
        p1 = p1.Next
        p2 = p2.Next
    }
    
    // 恢复链表
    slow.Next = reverseList(secondHalf)
    
    return true
}

// 反转链表
func reverseList(head *ListNode) *ListNode {
    var prev *ListNode
    curr := head
    
    for curr != nil {
        next := curr.Next
        curr.Next = prev
        prev = curr
        curr = next
    }
    
    return prev
}

时间复杂度:O(n)

  • 遍历链表以找到中点:O(n/2) = O(n)
  • 反转链表的后半部分:O(n/2) = O(n)
  • 比较两部分链表的节点值:O(n/2) = O(n)
  • 恢复链表的后半部分:O(n/2) = O(n)

总体时间复杂度为 O(n)。

空间复杂度:O(1)

  • 使用常量级别的额外空间,没有随链表长度变化的空间消耗。