leetcode#234. Palindrome Linked List

57 篇文章 0 订阅
14 篇文章 0 订阅

Description

Given a singly linked list, determine if it is a palindrome.

Follow up:
Could you do it in O(n) time and O(1) space?

Code

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

class Solution:
    def isPalindrome(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if head == None or head.next == None:
            return True
        llen = lpos = 0
        temp = head
        while temp != None:
            llen += 1
            temp = temp.next
        lpos = llen // 2 - 1
        cnt = 0
        pre = None
        right = head
        while cnt <= lpos:
            if cnt == lpos:
                right = head.next if llen % 2 == 0 else head.next.next
            cnt += 1
            temp = head.next
            head.next = pre
            pre = head
            head = temp
        while not pre == None:
            if pre.val != right.val:
                return False
            pre = pre.next
            right = right.next
        return True

按照O(n)时间复杂度,O(1)空间复杂度做的。具体的思想就是找到中间点,然后将前面的列表反转,这样才能遍历2n次就判断出结果,同时空间复杂度是O(1)。
去讨论里看了大神们的答案,发现了精彩的讨论,哈哈哈 该题在leetcode中精彩的评论
回到问题本身,发现大神就是大神,同样的逻辑,写出来的代码更简洁,就是看不懂(其实这并不是件好事…)。先贴在下面回头看。

Code(StefanPochmann)

Solution 1: Reversed first half == Second half?

Phase 1: Reverse the first half while finding the middle.
Phase 2: Compare the reversed first half with the second half.

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

Solution 2: Play Nice

Same as the above, but while comparing the two halves, restore the list to its original state by reversing the first half back. Not that the OJ or anyone else cares.

def isPalindrome(self, head):
    rev = None
    fast = head
    while fast and fast.next:
        fast = fast.next.next
        rev, rev.next, head = head, rev, head.next
    tail = head.next if fast else head
    isPali = True
    while rev:
        isPali = isPali and rev.val == tail.val
        head, head.next, rev = rev, head, rev.next
        tail = tail.next
    return isPali

看了看,果然屌呀。的确是在做同样的事,可就是那么短的代码就完成了。找到中点的同时还将前半段给反转了,的确可以这么做,可我的确没想到能合在一起。学习学习,以后就知道了。

Conclusion

虽然是简单题,但是大神写的代码依然是和常人不一样…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值