题目:
请编写一个函数,检查链表是否为回文。
给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文。
测试用例:
{1,2,3,2,1}返回: true
{1,2,3,2,3}返回:false
思路:
判断一个链表是不是回文串,就是看前半部分是否等于后半部分的逆序。所以可以利用快慢指针。假设一个指针quick每次向后移动两个结点,另一个指针slow每次向后移动一个结点,那么quick到达末尾时,slow正好到达链表中间位置。此时将slow之后的结点翻转,然后同时从head和slow.next开始遍历,就可以判断前半部分是否和后半部分相等。
那么为何快指针到达末尾时,慢指针正好到达中部?奇数个结点和偶数个结点是否有差别?
假设quick指针和slow指针初始时都位于第一个结点的位置,而链表总共n个结点,每一次前进,quick+2,slow+1。那么quick指针在第k次前进时到达末尾,即2k+1 = n(n为奇数) 或 2k+1 = n+1(n为偶数),而slow到达k+1(n为奇数)或k(n为偶数)。所以slow总是等于n/2向上取整,正好是中部。
代码:
# -*- coding:utf-8 -*-
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Palindrome:
def isPalindrome(self, pHead):
def reverse(head): #此处使用头插法进行翻转操作
if not head or not head.next:
return head
cur = head.next
while cur.next:
tmp = cur.next
cur.next = cur.next.next
tmp.next = head.next
head.next = tmp
slow, quick = pHead, pHead
while quick.next: #快慢指针
quick = quick.next
if quick.next:
quick = quick.next
else:
break
slow = slow.next
tmp = slow
reverse(slow)
quick = slow.next
slow = pHead
while quick:
if quick.val != slow.val:
reverse(tmp.next) #最后恢复链表
return False
quick = quick.next
slow = slow.next
reverse(tmp.next) #最后恢复链表
return True