Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
题意:给定一个链表,判断其是否为回文链表 eg:1 2 3 2 1 or 1 2 2 1
思路:找到中心点,前后对比
思路一:考虑到单链表缺失从后向前的信息(单链表的特性之一),如果能得到双向信息将很容易判断回文。
故考虑将单链表的节点值记录到一个数组中,判断数组是否回文;或通过一次遍历将单链表拓展成双向链表,再判断是否回文。
空间复杂度为O(n),时间复杂度为O(n)
runtimes:138ms
思路二:反转前半部分或后半部分,再与另一部分对比
空间复杂度为O(n/2),时间复杂度为O(n)
runtimes:318ms
可参考Reverse Linked List三种思路,其中:
采用思路一,空间复杂度为O(n/2),时间复杂度为O(n)
采用思路二,空间复杂度为O(1),时间复杂度为O(n)
runtimes:142ms
采用思路三,空间复杂度为O(n^2/8)
参考于:http://blog.csdn.net/coder_orz/article/details/51306985
方法1:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def isPalindrome(self, head):
if not head or not head.next:
return True
newList=[]
while head:
newList.append(head.val)
head=head.next
for i in range(len(newList)/2):
if newList[i]!=newList[len(newList)-i-1]:
return False
return True
方法二:
class Solution(object):
def isPalindrome(self, head):
if not head or not head.next:
return True
newList=[]
#快慢指针法找中点
slow=fast=head
while fast and fast.next:
newList.insert(0,slow.val)
fast=fast.next.next
slow=slow.next
if fast:
#链表结点数为奇数,slow指向中点,需要指向下一个结点才能够与反转链表比较
slow=slow.next
for i in range(len(newList)):
if slow.val!=newList[i]:
return False
else:
slow=slow.next
return True
方法三:
class Solution(object):
def isPalindrome(self, head):
if not head or not head.next:
return True
#快慢指针法找中点
slow=fast=head
while fast and fast.next:
fast=fast.next.next
slow=slow.next
if fast:
slow=slow.next
newhead=reverseList(self,slow)
while newhead:
if newhead.val!=head.val:
return False
newhead=newhead.next
head=head.next
return True
def reverseList(self, head):
newhead=None
while head:
p=head
head=head.next
p.next=newhead
newhead=p
return newhead