【題目】
給定一個鏈表的頭節點head,請判斷該鏈表是否爲迴文結構。
進階:如果鏈表長度爲N,要求時間複雜度O(N),空間複雜度O(1)。
【基本思路】
方法一。時間複雜度O(N),空間複雜度O(N)。
使用棧,遍歷一遍鏈表把每個節點都壓入棧中,這樣在彈出棧的時候,所有的節點就逆序了。依次對比原鏈表的每個節點即可。
#python3.5
def isPalindrome1(head):
if head == None or head.next == None:
return True
stack = []
cur = head
while cur != None:
stack.append(cur)
cur = cur.next
while stack:
if stack.pop().val != head.val:
return False
head = head.next
return True
方法二。時間複雜度O(N),空間複雜度O(N/2)。
也使用棧,但是這次只將鏈表的後半部分壓入棧中,這樣在彈出棧的時候,後半部分的節點就逆序了。依次對比鏈表的前半部分和逆序後的後半部分的每個節點即可。
def isPalindrome2(head):
if head == None or head.next == None:
return True
stack = []
pre = head.next
cur = head
while cur.next != None and cur.next.next != None:
pre = pre.next
cur = cur.next.next
while pre != None:
stack.append(pre)
pre = pre.next
while stack:
if stack.pop().val != head.val:
return False
head = head.next
return True
方法三。時間複雜度O(N),空間複雜度O(1)。
首先改變鏈表右半區的結構,使整個右半區的指針反指,中間節點的next指向None。接下來從兩端開始向中間依次對比即可。需要注意的是,再判斷完畢後要將鏈表調整會原鏈表的結構。
def isPalindrome3(head):
if head == None or head.next == None:
return True
pre = head
cur = head
while cur.next != None and cur.next.next != None:
pre = pre.next
cur = cur.next.next
node = pre.next
pre.next = None
while node != None:
next = node.next
node.next = pre
pre = node
node = next
node = pre
res = True
while pre != None and head != None:
if pre.val != head.val:
res = False
break
pre = pre.next
head = head.next
pre = node.next
node.next = None
while pre != None:
next = pre.next
pre.next = node
node = pre
pre = next
return res