【算法题】判断链表是回文链表

思路:

将链表反转,然后和原链表对比,如果相等即为回文链表。

  1. 记录当前节点和之前和之后的节点
  2. 将当前节点的指针反转,由指向后一个节点改为指向前一个节点(没有前面节点时, 指向None)
  3. 依次处理下一个数据,直到最后一个数据,将其指向新链表的头即可

代码如下, 定义一个反转链表的函数reverse

In [10]: class Node:
    ...:     def __init__(self, value, next=None):
    ...:         self.value = value
    ...:         self.next = next
    ...:     def __repr__(self):
    ...:         head = self
    ...:         repr = ''
    ...:         while head:
    ...:             repr += f'{head.value} -> '
    ...:             head = head.next
    ...:         repr += 'None'
    ...:         return repr

In [11]: def reverse(node):
    ...:     former = None
    ...:     while node.next:
    ...:         latter = node.next    
    ...:         node.next = former  # 重定向指针方向
    ...:         former, node = node, latter # 移动当前节点和之前节点的位置
    ...:     node.next = former  # 最后一个节点指向新链表的头
    ...:     return node

In [12]: node6 = Node(6)
    ...: node5 = Node(5, node6)
    ...: node4 = Node(4, node5)
    ...: node3 = Node(3, node4)
    ...: node2 = Node(2, node3)
    ...: node1 = Node(1, node2)

In [13]: node1
Out[13]: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> None

In [14]: reversed_node = reverse(node1)
In [15]: reversed_node
Out[15]: 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> None

In [16]: from copy import deepcopy
   ...: def is_palindrome(node):
   ...:     node_copy = deepcopy(node)
   ...:     reversed_node = reverse(node_copy)
   ...:     print(node)
   ...:     print(reversed_node)
   ...:     while node:
   ...:         if not node.value == reversed_node.value:
   ...:             return False
   ...:         node, reversed_node = node.next, reversed_node.next
   ...:     return True

In [17]: is_palindrome(node1)
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> None
6 -> 5 -> 4 -> 3 -> 2 -> 1 -> None
Out[17]: False

In [18]: node6 = Node(1)
    ...: node5 = Node(2, node6)
    ...: node4 = Node(3, node5)
    ...: node3 = Node(3, node4)
    ...: node2 = Node(2, node3)
    ...: node1 = Node(1, node2)

In [19]: is_palindrome(node1)
1 -> 2 -> 3 -> 3 -> 2 -> 1 -> None
1 -> 2 -> 3 -> 3 -> 2 -> 1 -> None
Out[19]: True

② 提高性能的方法

结合 单向链表的中间节点, 可以找到链表的中点后,反转后一半儿链表,然后和原链表的前一半进行比较。

In [1]: class Node:
   ...:     def __init__(self, value, next=None):
   ...:         self.value = value
   ...:         self.next = next
   ...:     def __repr__(self):
   ...:         head = self
   ...:         repr = ''
   ...:         while head:
   ...:             repr += f'{head.value} -> '
   ...:             head = head.next
   ...:         repr += 'None'
   ...:         return repr

In [2]: def get_middle(node):
   ...:     slow, fast = node, node
   ...:     while fast and fast.next:
   ...:         slow = slow.next
   ...:         fast = fast.next.next
   ...:     return slow
   ...:

In [3]: def reverse(node):
   ...:     former = None
   ...:     while node.next:
   ...:         latter = node.next
   ...:         node.next = former
   ...:         former, node = node, latter
   ...:     node.next = former
   ...:     return node
   ...:

In [4]: def is_palindrome(node):
   ...:     middle = get_middle(node)
   ...:     reversed_half = reverse(middle)
   ...:     while reversed_half:
   ...:         if not node.value == reversed_half.value:
   ...:             return False
   ...:         node, reversed_half = node.next, reversed_half.next
   ...:     return True

In [5]: node6 = Node(1)
   ...: node5 = Node(2, node6)
   ...: node4 = Node(3, node5)
   ...: node3 = Node(3, node4)
   ...: node2 = Node(2, node3)
   ...: node1 = Node(1, node2)

In [6]: is_palindrome(node1)
Out[6]: True

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值