Leetcode刷题笔记30-回文链表

1. 题目

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

2. 示例

示例 1:

输入: 1->2
输出: false

示例 2:

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

3. 解答

python3

将链表的每个结点记录在数组中,在进行数值判别。时间复杂度为O(n),空间复杂度为O(n)。

class Solution(object):
    def isPalindrome(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        listnode = []
        while head:
            listnode.append(head)
            head = head.next
        for i in range(int(len(listnode)/2)):
            if listnode[i].val != listnode[len(listnode)-i-1].val:
                return False
        return True

solution = Solution()
head = ListNode(0)
# cur = head
# for i in range(1, 5):
#     node = ListNode(i)
#     cur.next = node
#     cur = node
n1 = ListNode(1)
head.next = n1
n2 = ListNode(2)
n1.next = n2
n3 = ListNode(2)
n2.next = n3
n4 = ListNode(1)
n3.next = n4
n5 = ListNode(0)
n4.next = n5
print(head)
s = solution.isPalindrome(head)
print(s)

4. 优答

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

算法思想:

(1)找到中间结点

(2)将后面半部分的结点进行反转(也可用使用栈的后进先出的特性,但是空间复杂度就是O(n/2))

(3)比较前面半部分和后面半部分结点的大小

技巧:

(1)单链表找中点:使用快慢指针同步计数,每次快指针走两步,慢指针走一步,当快指针走完时,慢指针刚好走了一半,正好索引到链表的中点。

(2)链表逆序可以参看之前的题:单链表逆序。

class Solution(object):
    def reverseList(self, head):
        if head == None: return head
        pre = head
        cur = head.next
        while cur != None:
            pre.next = cur.next
            cur.next = head
            head = cur
            cur = pre.next
        return head

    def isPalindrome(self, head):
        if head is None or head.next is None: return True
        fast = slow = head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
        # slow = self.reverseList(slow)
        ##### 这里面要考虑奇偶数的问题。
        # 如果是奇数个结点,那么fast是指向最后一个元素,它的next为None。
        # 如果是偶数个结点,那么fast是None。
        if fast:    # 奇数个结点,slow指向的是中间那个结点,要逆序的是中间结点后面的链表
            slow.next = self.reverseList(slow.next)
            slow = slow.next
        else:       # 偶数个结点,slow指向的是后面要逆序链表的头结点
            slow = self.reverseList(slow)
        while slow:
            if head.val != slow.val:
                return False
            head = head.next
            slow = slow.next
        return True

solution = Solution()
head = ListNode(0)
# cur = head
# for i in range(1, 5):
#     node = ListNode(i)
#     cur.next = node
#     cur = node
n1 = ListNode(1)
head.next = n1
n2 = ListNode(2)
n1.next = n2
n3 = ListNode(2)
n2.next = n3
n4 = ListNode(1)
n3.next = n4
n5 = ListNode(0)
n4.next = n5
print(head)
s = solution.isPalindrome(head)
print(s)

另一种解答:

class Solution:
    def isPalindrome(self, head):
        reverse, fast = None, head
        # Reverse the first half part of the list.
        while fast and fast.next:
            fast = fast.next.next
            head.next, reverse, head = reverse, head, head.next

        # If the number of the nodes is odd,
        # set the head of the tail list to the next of the median node.
        tail = head.next if fast else head

        # Compare the reversed first half list with the second half list.
        # And restore the reversed first half list.
        is_palindrome = True
        while reverse:
            is_palindrome = is_palindrome and reverse.val == tail.val
            reverse.next, head, reverse = head, reverse, reverse.next
            tail = tail.next

        return is_palindrome

猜你喜欢

转载自www.cnblogs.com/Joyce-song94/p/9190869.html
今日推荐