leetcode 234:用链表实现回文检测

在这里插入图片描述
Time complexity: O(n)
Space complexity: O(1)

想法:将linked list对半切开,分为first half和second half,再将second half倒转并与first half进行比较。比较完成后,将second half还原并与first half相连。

代码:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def isPalindrome(self, head: Optional[ListNode]) -> bool:
        #如果linked list只有一个node,返回True。
        if head.next == None:
            return True
        
        #在将linked list对半切开时,我们需要找到中间点。
        #建立两个指针,慢指针每次移动一步,快指针每次移动两步。
        #当linked list的长度为偶数时,快指针最后会指向None,慢指针会指向second half的第一个node。
        slow_ptr = head
        fast_ptr = head
        
        #记录慢指针指向的前一个node,它最后会作为first half的结尾。
        prev_of_slow_ptr = head
        
        #当linked list的长度为奇数时,快指针最后会指向链表最后一个node,慢指针会指向恰好位于中间的node。
        #我们在比较first half与second half时,不需要考虑中间这个node,所以用midNode表示。
        midNode = None
        res = True
        
        #用两个指针遍历这个链表。
        while fast_ptr != None and fast_ptr.next != None:
            fast_ptr = fast_ptr.next.next
            prev_of_slow_ptr = slow_ptr
            slow_ptr = slow_ptr.next
        
        #如果快指针最后不等于None,证明链表长度是奇数。
        #我们将中间点表示为midNode,把慢指针移后一位,指向second half的开头。
        if fast_ptr != None:
            midNode = slow_ptr
            slow_ptr = slow_ptr.next
        
        
        second_half = slow_ptr
        
        #切断first half和second half。
        prev_of_slow_ptr.next = None
        
        #将second half倒转。
        second_half = self.reverse(second_half)
        
        #比较first half和second half。
        res = self.compare(head, second_half)
        
        #将second half还原。
        second_half = self.reverse(second_half)
        
        #将second half与first half相连。
        if midNode != None:
            prev_of_slow_ptr.next = midNode
            midNode.next = second_half
        else:
            prev_of_slow_ptr.next = second_half
        
        return res
        
        
        
        
    def reverse(self, half_list):
        prev = None
        current = half_list
        next = None
        
        while (current != None):
            next = current.next
            current.next = prev
            prev = current
            current = next
        new_half_list = prev
        return new_half_list
    
    def compare(self, head1, head2):
        temp1 = head1
        temp2 = head2
        
        while temp1 != None and temp2 != None:
            if temp1.val == temp2.val:
                temp1 = temp1.next
                temp2 = temp2.next
            else:
                return False
            
        if temp1 == None and temp2 == None:
            return True
        
        return False
        
            
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值