链接:
题目:
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