【题目】 给定一个链表的头节点head,请判断该链表是否为回 文结构。
例如:
1->2->1,返回true
1->2->2->1,返回true
15->6->15,返回true
1->2->3,返回false
进阶: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂 度达到O(1)
方法一:需要一个额外的栈结构,并且把所有的节点都压入栈结构,所以这个额外的栈结构需要O(N)的空间
def isPalindromel(head):
if head==None or head.next==None:
return True
stack = []
cur = head
while cur!=None:
stack.append(cur)
cur = cur.next
while head!=None:
if head.value!=stack.pop().value:
return False
head = head.next
return True
方法二
def isPalindrome2(head):
"""
时间复杂度为O(N),空间复杂度为O(N/2),使用栈,只将链表的后半部分压入栈中,弹出栈时和前半部分比较
"""
if head == None or head.next == None:
return True
right = head.next
pre = head
while pre.next != None and pre.next.next != None:
pre = pre.next.next
right = right.next
stack = []
while right!=None:
stack.push(right)
right = right.next
while stack.isEmpty():
if stack.pop().value!=head.value:
return False
head = head.next
return True
方法三
def isPalindrome3(head):
"""
时间复杂度O(N),空间复杂度为O(1),改变链表右半区结构,使整个右半区的指针反转,中间节点next指向None
接下来从两端向中间一次对比,判断完之后需要将链表还原为原来的结构
"""
if head == None or head.next.next == None:
return True
n1 = head
n2 = head
"""
查找中间节点n1
"""
while n2.next!=None and n2.next.next!=None:
n2 = n2.next.next
n1 = n1.next
"""
右侧第一个节点
"""
n2 = n1.next
n1.next = None
"""
右半区反转
"""
n3 = None
while n2!=None:
n3 = n2.next
n2.next = n1
n1 = n2
n2 = n3
n3 = n1
n2 = head
res = True
"""
检查回文
"""
while n1!=None and n2!= None:
if n1.value!=n2.value:
res = False
break
n1 = n1.next
n2 = n2.next
"""
恢复原来的结构
"""
n1 = n3.next
n3.next = None
while n1 != None:
n2 = n2.next
n1.next = n3
n3 = n1
n1 = n2
return res