简体   繁体   中英

Python linked list cannot save head node

This is about a leetcode question:"234. Palindrome Linked List"

I wanted to reverse the linked list and compare the reversed with the original list. If there is no difference then return True.

But the strange thing is, although I copied head to a dummy node, to record the starting position. After reversing the list, I cannot iterate from the dummy node, seems that there is only 1 element left in the list.

Why/How did the dummy node get updated? This bugs me so hard that I want to bang my head to the wall.

Any help is appreciated!

Thanks!

I've tried everything I could based on my limited knowledge.

# 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
        """


        dummy = head
        prev = None

        while head:
            temp = head
            head = head.next
            temp.next = prev
            prev = temp  

        while prev and dummy:
            print prev.val, dummy.val

            if prev.val != dummy.val:
                return False

            prev = prev.next
            dummy = dummy.next

        return True

I expect the code above to be working

From your code, I think your idea is reverse the linklist, and compare with the original one, but it is incorrect to do that. Because you change on original linklist, you can not do comparison anymore, so you have to make a copy, but it is an inefficient solution.

I have edited copy version based on your code, it works, but it is not the best way to do it.

def isPalindrome(self, head):
    dummy = head
    prev = None
    cur = origin = ListNode(0)

    # copy the original linkedlist
    while head:
        cur.next = ListNode(head.val)
        head = head.next
        cur = cur.next

    head = dummy
    while head:
        temp = head
        head = head.next
        temp.next = prev
        prev = temp

    cur = origin.next
    while prev and cur:
        print(prev.val, cur.val)

        if prev.val != cur.val:
            return False

        prev = prev.next
        cur = cur.next

    return True

a better idea to do it is reverse the first half of LinkList, and compare whether first half is equal to second half:

def isPalindrome(self, head):
    if not head or not head.next:
        return True
    count, cur = 0, head
    while cur:
        cur = cur.next
        count += 1

    pre, cur, post = None, head, head.next
    for _ in range(count // 2):
        cur.next = pre
        pre, cur, post = cur, post, post.next
    head.next = cur

    slow = pre
    fast = cur.next if count % 2 else cur

    for _ in range(count // 2):
        if slow.val != fast.val:
            return False
        slow, fast = slow.next, fast.next

    return True

more elegant version, but not so easy-understanding:

def isPalindrome(self, head):
    check = None
    slow = fast = head
    # traverse and reverse
    while fast and fast.next:
        fast = fast.next.next
        check, check.next, slow = slow, check, slow.next

    if fast:
        slow = slow.next
    while slow and slow.val == check.val:
        slow = slow.next
        check = check.next
    return not check

Hope that helps you, and comment if you have further questions. : )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM