【问题标题】:Leetcode 234: Palindrome LinkedListLeetcode 234:回文链表
【发布时间】:2021-08-11 15:07:28
【问题描述】:

我正在寻找234. Palindrome Linked List 的解决方案:

给定单链表的head,如果是回文则返回true

这是一个正确的解决方案:

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        #Null condition
        if head == None:
            return True
        
        #move fast and slow pointers
        s_p = head
        f_p = head
        while(f_p.next != None and f_p.next.next != None):
            s_p = s_p.next
            f_p = f_p.next.next
            
        #reverse slow pointer
        first_half = self.reverse(s_p)     
        
        #compare
        while(first_half != None and head != None):
            print(first_half.val)
            print(head.val)
            if(first_half.val != head.val):
                return False
            first_half = first_half.next
            head = head.next
        
        return True
    
    def reverse(self,c_p):
        
        prev_head = None
        
        while(c_p != None):
            temp = c_p.next
            c_p.next = prev_head
            prev_head = c_p
            c_p = temp
        
        return prev_head

但我很难理解为什么该代码有效。

示例:1 -> 2 -> 2 -> 1

根据这个YouTube video的想法是我们取列表的前半部分,反转它,然后比较。

插图说我们将比较一个指向 1 -> 2 -> Null 的指针与另一个指针 1 -> 2 -> Null 反转后。

虽然从我所见,这实际上是在比较 first_half : 1 -> 2 -> 2 -> Null 到 头部:1 -> 2 -> 空。

此代码确实通过了所有测试用例,但我希望 2nd 代码(我的修改版本)也应该可以工作,但它没有:

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        #Null condition
        if head == None:
            return True
        
        #move fast and slow pointers
        s_p = head
        f_p = head
        while(f_p.next != None and f_p.next.next != None):
            s_p = s_p.next
            f_p = f_p.next.next
        
        #set s_p.next to Null
        s_p.next = None

        #reverse fast pointer
        second_half = self.reverse(f_p)
        
     
        
        #compare
        while(second_half != None and head != None):
            print(second_half.val)
            print(head.val)
            if(second_half.val != head.val):
                return False
            second_half = second_half.next
            head = head.next
        
        return True
    
    def reverse(self,c_p):
        
        prev_head = None
        
        while(c_p != None):
            temp = c_p.next
            c_p.next = prev_head
            prev_head = c_p
            c_p = temp
        
        return prev_head

这样,我所做的就是将第二个指针反转:2 -> 1 -> Null 到 1 -> 2 -> Null

现在我们可以将 head 与反转的下半场进行比较。

它没有通过 LeetCode 中的测试,但我很困惑为什么不。

我知道这是一个简单的问题,但我仍在苦苦挣扎。

非常感谢任何帮助。

【问题讨论】:

    标签: python linked-list singly-linked-list


    【解决方案1】:

    根据这个 YouTube 视频的想法......我们取列表的前半部分,将其反转,然后进行比较。

    这是一个误解。它实际上反转了列表的 second 一半。正确的代码反转从s_p(慢指针)开始的列表。这不是列表的前半部分,而是后半部分。前半部分将从整个列表开始的位置开始:head。当f_p 接近列表末尾时,让s_pf_p 引用遍历列表的循环将结束,因此s_p 是列表的一半。

    您的代码反转了从f_p(快速指针)开始的列表,但该指针指向列表中的最后一个或最后一个节点(查看while 条件),所以如果有的话,它只反转列表的最后两个节点!这显然是不正确的。

    【讨论】:

    • 我明白了,这是有道理的。谢谢。
    • 不要忘记将答案标记为已接受。
    【解决方案2】:

    您的修改版本中有一个错误
    您的逻辑是正确的,但是当您的反向函数被定义为从参数传递中反转列表时,f_p 将指向最后一个元素,而不是中间元素。 leetcode 版本解决方案是比较从开始的值和倒过来的后半部分的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-27
      • 1970-01-01
      • 1970-01-01
      • 2013-02-09
      • 2021-08-20
      相关资源
      最近更新 更多