📜  门|门CS 2008 |问题 1(1)

📅  最后修改于: 2023-12-03 15:42:22.350000             🧑  作者: Mango

门|门CS 2008 | 问题 1

这道问题一是一道典型的双指针问题,需要使用两个指针来操作。具体来说,我们可以使用一前一后两个指针,将它们初始化为链表的头指针,然后同时开始向后移动。如果两个指针指向的元素相同,就将前面的指针向后移动,否则就将两个指针都向后移动。

解题思路
分析题目:

题目要求判断一个链表是否为回文链表,我们可以将链表从中间分成两部分,再将后半部分反转(也可以将前半部分反转,对算法的时间复杂度影响不大),比较前半部分和后半部分是否相同。

解答步骤:
  1. 设置两个指针 fastslow,都指向链表头结点
  2. fast指针每次移动两个结点,slow指针每次移动一个结点
  3. fast 到达链表尾部时,slow 刚好到达链表中间,分为前后两个部分
  4. 将后半部分反转(可以使用规范的链表反转算法)
  5. 分别比较前半部分和后半部分是否相等
  6. 恢复链表原状,返回比较结果
代码实现:
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        if not head or not head.next:
            return True
        
        slow, fast = head, head
        while fast.next and fast.next.next:
            slow = slow.next
            fast = fast.next.next
        
        def reverseList(head):
            pre = None
            cur = head
            while cur:
                tmp = cur.next
                cur.next = pre
                pre = cur
                cur = tmp
            return pre
        
        head_second_half = reverseList(slow.next)
        p1, p2 = head, head_second_half
        while p2:
            if p1.val != p2.val:
                break
            p1 = p1.next
            p2 = p2.next
        
        reverseList(head_second_half)
        if p2:
            return False
        else:
            return True
总结

这道题考察了指针、链表和回文问题,虽然表面上看起来比较简单,但有些细节需要注意,特别是链表的反转操作,需要掌握相应的算法才能顺利通过题目。