链接:
题目:
Given a singly linked list, determine if it is a palindrome.Example:
Example 1:Input: 1->2
Output: false
Example 2:
Input: 1->2->2->1
Output: true
Notes:
Could you do it in O(n) time and O(1) space?解析:
算法有以下几种:
- 遍历整个链表,将链表每个节点的值记录在数组中,再判断数组是不是一个回文数组,时间复杂度为O(n),但空间复杂度也为O(n),不满足空间复杂度要求。
- 利用栈先进后出的性质,将链表前半段压入栈中,再逐个弹出与链表后半段比较。时间复杂度O(n),但仍然需要n/2的栈空间,空间复杂度为O(n)。
- 反转链表法,将链表后半段原地翻转,再将前半段、后半段依次比较,判断是否相等,时间复杂度O(n),空间复杂度为O(1)满足题目要求。
解答:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self,head):
p1 = None
p2 = head
while p2:
temp = p2.next
p2.next = p1
#更新p1,p2值
p1 = p2
p2 = temp
return p1
def isPalindrome(self, head):
"""
:type head: ListNode
:rtype: bool
"""
#如果链表为空或者仅有一个元素那么肯定是回文链表
if (not head) or (not head.next):
return True
#快慢指针法,寻找链表中心
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
#链表元素奇数个
if fast:
slow.next = self.reverseList(slow.next)
slow = slow.next
#链表元素偶数个
else:
slow = self.reverseList(slow)
while slow:
if head.val != slow.val:
return False
slow = slow.next
head = head.next
return True
不考虑链表长度是奇数还是偶数,简化如下:
# 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):
"""
:type head: ListNode
:rtype: bool
"""
#如果链表为空或者仅有一个元素那么肯定是回文链表
if (not head) or (not head.next):
return True
#快慢指针法,寻找链表中心
fast = slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
# 反转后半部分
node = None
while slow:
nxt = slow.next
slow.next = node
node = slow
slow = nxt
# 比较前半部分和后半部分
while node: # while node and head:
if node.val != head.val:
return False
node = node.next
head = head.next
return True