只用单链表的方式判断一个链表是否为回文链表

思路

  • 寻找链表的中点:使用快慢指针的方法,快指针每次移动两步,慢指针每次移动一步。当快指针到达链表末尾时,慢指针正好位于链表的中间。

  • 反转后半部分链表:从中点开始反转链表的后半部分。

  • 比较前半部分和反转后的后半部分:逐一比较两个部分的节点值,如果所有对应的节点值都相同,则链表是回文的。

  • (可选)恢复链表的原始结构:将反转的后半部分再反转回来,以恢复原链表结构。

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def isPalindrome(head: ListNode) -> bool:
    if head is None or head.next is None:
        return True

    # Step 1: Find the end of the first half
    first_half_end = end_of_first_half(head)
    
    # Step 2: Reverse the second half
    second_half_start = reverse_list(first_half_end.next)
    
    # Step 3: Compare the first half and the reversed second half
    p1 = head
    p2 = second_half_start
    result = True
    while result and p2 is not None:
        if p1.val != p2.val:
            result = False
        p1 = p1.next
        p2 = p2.next
    
    # Step 4: Restore the list (optional)
    first_half_end.next = reverse_list(second_half_start)
    
    return result

def end_of_first_half(head: ListNode) -> ListNode:
    fast = head
    slow = head
    # Move fast by 2 steps and slow by 1 step until fast reaches the end
    while fast.next is not None and fast.next.next is not None:
        fast = fast.next.next
        slow = slow.next
    return slow

def reverse_list(head: ListNode) -> ListNode:
    previous = None
    current = head
    while current is not None:
        next_node = current.next
        current.next = previous
        previous = current
        current = next_node
    return previous

 

posted @ 2024-09-25 18:21  最小生成树  阅读(5)  评论(0编辑  收藏  举报