LeetCode 234. Palindrome Linked List

题目

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false

示例 2:

输入: 1->2->2->1
输出: true

进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

思路

我想到了要将链表逆序,然后再比较前一半和后一半,但我没想到怎么找到中点,有点没转过来脑筋。所以就用了比较笨的方法,空间复杂度高,时间还好。先求出列表长度,然后走一半压栈,然后一个个弹出和后面的比较。
代码:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def isPalindrome(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        lenth = 0
        stack = []
        temp1 = temp2 = head
        while temp1:
            lenth += 1
            temp1 = temp1.next
        if lenth%2 == 0:
            for i in range(lenth/2):
                stack.append(temp2.val)
                temp2 = temp2.next
            for j in range(lenth/2):
                item = stack.pop()
                if item == temp2.val:
                    temp2 = temp2.next
                else:
                    return False
            return True
        else:
            for i in range((lenth-1)/2):
                stack.append(temp2.val)
                temp2 = temp2.next
            temp2 = temp2.next
            for j in range((lenth-1)/2):
                item = stack.pop()
                if item == temp2.val:
                    temp2 = temp2.next
                else:
                    return False
            return True

优化:

思路上来说就是将前一半的反向,然后和后一半进行比较,用了一个小trick,就是用了一个fast标记一次走两步,slow一次走一步,则fast走的是第奇数个节点,这样当fast and not fast.next为真的时候,就说明长度为奇数,并且slow在正中间,如果not fast为真的时候,说明长度为偶数,slow在中间两个相同数字的第二个。
代码:

def isPalindrome(self, head):
    rev = None
    slow = fast = head
    while fast and fast.next:
        fast = fast.next.next
        rev, rev.next, slow = slow, rev, slow.next
    if fast:
        slow = slow.next
    while rev and rev.val == slow.val:
        slow = slow.next
        rev = rev.next
    return not rev

附上评论区一段比较好的解释:

def isPalindrome(self, head):
    # rev records the first half, need to set the same structure as fast, slow, hence later we have rev.next
    rev = None
    # initially slow and fast are the same, starting from head
    slow = fast = head
    while fast and fast.next:
        # fast traverses faster and moves to the end of the list if the length is odd
        fast = fast.next.next
        
        # take it as a tuple being assigned (rev, rev.next, slow) = (slow, rev, slow.next), hence the re-assignment of slow would not affect rev (rev = slow)
        rev, rev.next, slow = slow, rev, slow.next
    if fast:
       # fast is at the end, move slow one step further for comparison(cross middle one)
        slow = slow.next
    # compare the reversed first half with the second half
    while rev and rev.val == slow.val:
        slow = slow.next
        rev = rev.next
    
    # if equivalent then rev become None, return True; otherwise return False 
    return not rev
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值