判断单链表字符串是否为回文字符串
例如:abcba 上海自来水来自海上
思想:利用快慢指针,快指针一次走两格,慢指针一次一个,因为这个字符串为单数,当快指针走到尾,慢指针正好走到中间,将这个中值保存下来,利用一个函数将后半部分反转(因为中值已经被记录,中值.next就是后半部分的head),用一个比较函数比较,当反转的字符串走完(长度为n/2 - 1),已经比较完成,返回结果。
下面是python3实现:
from typing import Optional
class Node:
def __init__(self, date: int, next= None):
self.date = date
self._next = next
class SinglyLinkedList:
def __init__(self):
self._head = None
def find_by_value(self, value: int) -> Optional[Node]:
p = self._head
while p and p.date !=value:
p = p._next
return p
def find_by_index(self, index: int) -> Optional[Node]:
p = self._head
position = 0
while p and position != index:
p = p._next
position += 1
return p
def insert_value_to_head(self, value: int):
new_node = Node(value)
self.insert_node_to_head(new_node)
def insert_node_to_head(self, new_node: Node):
if new_node:
new_node._next = self._head
self._head = new_node
def insert_value_to_after(self, node: Node, value: int):
new_node = Node(value)
self.insert_node_to_after(node, new_node)
def insert_node_to_after(self, node: Node, new_node: Node):
if not node or not new_node:
return
new_node._next = node._next
node._next = new_node
def __repr__(self) -> str:
nums = []
current = self._head
while current:
nums.append(current.date)
current = current._next
if len(nums) > 0 :
return '->'.join(str(num) for num in nums)
else:
return ''
def reverseList(self, head: Node):#反序
#prev表示刚处理过的节点
prev = None
while head:
temp = head._next
head._next = prev
prev = head
head = temp
return prev
def findMiddle(self, head: Node):#寻找中值
if not head or not head._next:
return False
#两个指针
p = head
q = head
while q and q._next:
p = p._next
q = q._next._next
return p
def isPalindrome(self, head: Node):#判断是否为回文字符串
if not head or not head._next:
return False
#一个指针正常遍历
p = head
#找到中值,方便另一个指针找头
middle = self.findMiddle(head)
#另一个指针遍历后半部分的反序
q = self.reverseList(middle._next)
while p and q and p.date == q.date:
p = p._next
q = q._next
#遍历完成,若为回文,q肯定为空,p肯定指向中值
return q == None
if __name__ == '__main__':
l = SinglyLinkedList()
l.insert_value_to_head('a')
l.insert_value_to_head('b')
l.insert_value_to_head('c')
l.insert_value_to_head('b')
l.insert_value_to_head('a')
print(l.isPalindrome(l._head))