Python programming question 47 -- palindrome linked list

subject

Give you the head node of a single linked list. Please judge whether the linked list is a palindrome linked list. If yes, return True; Otherwise, False is returned.

For example:

The original linked list is converted to a list: [1, 2, 2, 1], and the returned result is True

The original linked list is converted to a list: [1, 2], and the returned result is False

explain:

  • When returning the result, the direction of each node in the linked list needs to be consistent with the beginning.

The definition of the known linked list node and the code for the conversion between the linked list and the list are as follows:

class ListNode:  # Single linked list
    def __init__(self, val=0, next=None):
        self.val = val  # Elements stored on linked list nodes
        self.next = next  # Point to the next linked list node


def list_to_list_node(numbers):  # Convert the list into a one-way linked list and return the head node of the linked list
    dummy_head = ListNode(0)
    pre = dummy_head
    for number in numbers:
        pre.next = ListNode(number)
        pre = pre.next
    pre = dummy_head.next
    return pre


def list_node_to_list(node):  # Convert one-way linked list to list
    result = []
    while node:
        result.append(node.val)
        node = node.next
    return result

Implementation idea 1

  • Store all the data in the original linked list into a list, and then judge whether to reply
  • To judge whether the list is palindrome, you can define two pointers: left and right. One moves back from the beginning and the other moves forward from the end. Each time you judge whether the elements pointed to are the same. If they are different, it means that they are not palindromes and return False directly

Code implementation 1

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        cur, length = head, 0
        result = []
        while cur is not None:  # Traverse the linked list and store the elements on all nodes in the list result
            length += 1
            result.append(cur.val)
            cur = cur.next
        left, right = 0, length - 1  # Define 2 pointers, one from the beginning and the other from the end
        while left < right:
            if result[left] != result[right]:  # If the elements corresponding to left and right are found to be inconsistent, it indicates that they are not palindromes
                return False
            left += 1
            right -= 1
        return True
  • Time complexity: O(n)
  • Space complexity: O(n)

Of course, after storing the linked list elements in the list result above, we can also directly compare the list with its inverted list. The code is as follows:

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        cur = head
        result = []
        while cur is not None:  # Traverse the linked list and store the elements on all nodes in the list result
            result.append(cur.val)
            cur = cur.next
        return result == result[::-1]

Implementation idea 2

  • It is implemented by using double pointers
  • Find the intermediate node from the linked list and divide the linked list into two parts: the first half and the second half. The first half is from the head node to the intermediate node of the original linked list, and the second half is from the next node to the last node of the intermediate node of the original linked list
  • Reverse the second half of the original linked list to get the reversed head node reverse_head
  • Define a variable to mark the final judgment result. The default value is True
  • Traverse two linked lists. The first half of the linked list moves from head, and the second half of the linked list reverses from reverse_head starts to move, and compares whether the node elements are consistent in turn. If not, mark the result as False, and break jumps out of the loop
  • After the comparison, because the original linked list is divided into two parts, you need to restore the direction of the original linked list first, and then return the final judgment result

Code implementation 2

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        if head is None:  # If it is an empty linked list, return True directly
            return True
        middle_node = self.get_middle_node(head)  # Find intermediate node
        reverse_head = self.reverse_list_node(middle_node.next)  # Invert from the next node of the intermediate node of the original linked list to the last node, and return the inverted head node
        flag, pre, post = True, head, reverse_head
        while post is not None:
            # The first half of the linked list starts from head, and the second half of the inverted linked list starts from reverse_ Start with head and compare whether the node elements are consistent
            if pre.val != post.val:
                flag = False
                break
            pre = pre.next
            post = post.next
        middle_node.next = self.reverse_list_node(reverse_head)  # Restore the original linked list
        return flag

    def get_middle_node(self, head: ListNode) -> ListNode:  # Find the intermediate node of the linked list
        slow, fast = head, head  # Define slow and fast pointers
        while fast.next is not None and fast.next.next is not None:
            slow = slow.next  # The slow pointer moves 1 bit at a time
            fast = fast.next.next  # The fast pointer moves 2 bits at a time
        return slow

    def reverse_list_node(self, head: ListNode) -> ListNode:  # Invert the linked list and return the inverted head node
        pre, cur = None, head
        while cur is not None:
            next_node = cur.next
            cur.next = pre
            pre = cur
            cur = next_node
        return pre
  • Time complexity: O(n)
  • Space complexity: O(1)

More Python programming questions are waiting for you to challenge: Python programming problem summary (continuously updated...)

Added by cornelalexa on Sun, 23 Jan 2022 08:14:44 +0200