打败算法 —— 回文链表

本文参考

出自LeetCode上的题库 —— 回文链表,本题比较简单,但既考察了单向链表反转,也可以应用快慢指针

https://leetcode-cn.com/problems/palindrome-linked-list/

回文链表问题

给定一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false

示例1:
输入: head = [1,2,2,1]
输出: true

示例2:
输入:head = [1,2]
输出:false

解题思路

第一种解法和"环形链表 II"相似,我们可以额外用一个列表存储各个节点的值,遍历完链表后,判断列表中的元素是否构成回文(Python的语法糖可以用一行代码实现)

第二种解法利用快慢指针,将第一种解法的$O(n)$空间复杂度降低到了$O(1)$。在"环形链表 II"中,我们利用快慢指针计算相遇位置公式,而在本题中,我们仍然利用 $d_{fast}=2d_{slow}$ 的性质,当快指针到达链表的末尾时,慢指针正好停留在中间节点的位置。注意,根据不同的限制条件,慢指针所在节点的值可能是回文的前半部分,也可能是回文的后半部分

得到中间位置后,只需倒置后半部分的节点链接方向,就能够完成回文的判断

O(n)空间复杂度解法

class ListNode:
  def __init__(self, val=0, next=None):
    self.val = val
    self.next = next

class Solution:
  def is_palindrome_1(self, head: ListNode) -> bool:
    if head is None:
      return False

    # 记录所有节点的值 

    curr_node = head
    node_values = list()
    while curr_node:
      node_values.append(curr_node.val)
      curr_node = curr_node.next

    # 判断是否是回文
        #  node_num = len(node_values)
    # for i in range(node_num // 2):
    # if node_values[i] != node_values[node_num - i - 1]:
    # return False
    # return True

    #
利用语法糖完成回文判断
    return node_values == node_values[::-1]

O(1)空间复杂度解法(快慢指针)

def is_palindrome_2(self, head: ListNode) -> bool:
  if head is None:
    return False

  slow = head
  fast = head

  # 使用快慢指针找到中间节点 

  while fast.next is not None and fast.next.next is not None:
    slow = slow.next
    fast = fast.next.next

  # 反转后半段单向链表 

  pre = None
  while
slow:
    next_node = slow.next
    slow.next = pre
    pre = slow
    slow = next_node

  # 判断是否是回文 

  tail = pre
  while head:
    if head.val != tail.val:
      return False
    head = head.next
    tail = tail.next
  return True

posted @ 2022-03-02 16:02  咕~咕咕  阅读(30)  评论(0编辑  收藏  举报