力扣(leetcode) 234. 回文链表 (后半段翻转法) 分步详解!!!!

题目在这:https://leetcode-cn.com/problems/palindrome-linked-list/

法一:(偷懒法)

思路分析
可以直接将链表里的元素放到列表里,然后判断是否回文即可。

完整代码:

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        res = []
        while head:
            res.append(head.val)
            head = head.next
        return True if res == res[::-1] else False

题目中还有个进阶。
要求时间复杂度 N 空间复杂度 1。
那就意味着我们不能开辟额外的空间了,只能原地判断。

法二: (后半段翻转法)

一个链表若回文,则从中间分开,两边应该是镜像的,也就是说。我们可以直接找到中心点,然后翻转后半段的链表,再依次比较是否相等就可以了。

  • 第一步找到中心点。

    使用快慢指针找中心点, 慢指针每次走一个单位,快指针每次走两个单位。这种情况下,当快指针指向最后一个元素(奇数个元素)或指向空值时(偶数个元素)慢指针刚好指向中间点(奇数个元素)或中间两个值的前一个值(偶数个元素)。
    这里如果没看懂的话,随便举个例子画一下就懂了,很好理解。

  • 第二步翻转后半段链表。
    关于链表的翻转,可以看我的另一篇文章,里面有详细的解释。

  • 第三步依次比较元素是否相等。:
    大家可以在纸上画一下,当后半段链表翻转结束后,最后一个指针应当指向了原始列表的末尾,这样我们只需要不断比较末尾指针和头指针是否相等即可,一直用 next就行了。
    结束条件:其中一个指针的下一个位置是另一个指针所指位置(偶数个元素)
    或者 两个指针的下一个位置指向同一个位置,(奇数个元素)

完整代码

 def isPalindrome(self, head: ListNode) -> bool:
       fast,slow = head,head
       while True: # 找到中间点的位置
            if fast.next == None: # 此时fast 指向奇数个数链表的 倒数第一个元素 
                break # solw指向中间节点
            if fast.next.next == None: # 此时fast 指向偶数个链表的 倒数第二个元素
               
                break  # 此时slow指向中间两个节点的前一个节点
            
            fast = fast.next.next
            slow = slow.next
       pre = slow.next

       while pre:  # 翻转后半段
           temp = pre.next
           pre.next = slow
           slow = pre
           pre = temp
           
       while True: # 前后半段进行比较
           if head.val != slow.val:
               return False
           if head.next == slow.next or head == slow.next:
               return True
           head = head.next
           slow = slow.next
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深度不学习!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值