Leetcode 234. Palindrome Linked List
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?
思路: 一开始我想到的方法伪码如下:
while head不空:
{做如下的事情: 保存表头,然后找到list中的最后一个元素,如果他们不等,那么输出False。如果他们相等,head前进一步,倒数第二个node指向None (等于删掉了list中的最后一个元素)。}
return True
但是和预想的一样,超时。
1 class Solution(object): 2 def isPalindrome(self, head): 3 """ 4 :type head: ListNode 5 :rtype: bool 6 """ 7 while head: 8 start = end = head 9 prev = ListNode(0) 10 while end.next: 11 prev = end 12 end = end.next 13 14 if start.val != end.val: 15 return False 16 else: 17 head = head.next 18 prev.next = None 19 20 return True
思路二: 然后想到了一个时间合理,但是space O(n)的解法。先看看list有多长。然后把前半截的node values逐个push到一个stack里。然后从后半截开始逐个比较node value和stack[-1]。注意list长度为奇偶的两种情况。奇数时,先pop掉中间一个。
1 class Solution(object): 2 def isPalindrome(self, head): 3 """ 4 :type head: ListNode 5 :rtype: bool 6 """ 7 if not head or not head.next: 8 return True 9 10 m = 0 11 start = head 12 while start: 13 start = start.next 14 m += 1 15 16 n = 1 17 stack = [] 18 start = head 19 if m%2 == 0: 20 while n <= m/2: 21 stack.append(start.val) 22 start = start.next 23 n += 1 24 25 while stack: 26 if start.val == stack[-1]: 27 start = start.next 28 stack.pop() 29 else: 30 return False 31 32 return True 33 else: 34 while n <= m//2+1: 35 stack.append(start.val) 36 start = start.next 37 n += 1 38 stack.pop() 39 while stack: 40 if start.val == stack[-1]: 41 start = start.next 42 stack.pop() 43 else: 44 return False 45 46 return True
解法三: 参考的书影的博客:http://bookshadow.com/weblog/2015/07/10/leetcode-palindrome-linked-list/
1). 使用快慢指针寻找链表中点
2). 将链表的后半部分就地逆置,然后比对前后两半的元素是否一致
tips: 1. 用slow, fast的方法最后,slow总在中间位,例如
1 2 3 4 3 2 1 1 2 3 3 2 1
slow slow
2. reverse list 注意一开始定义一个None。
3. 判断两个list时候相同书影的方法也很巧妙。由于奇偶的区别,p1的长度<=p2的长度。所以只要node value相同就都前进一步,最后只要看p1是否为空就可以。
1 class Solution(object): 2 def isPalindrome(self, head): 3 """ 4 :type head: ListNode 5 :rtype: bool 6 """ 7 if not head or not head.next: 8 return True 9 10 fast = slow = head 11 while fast.next and fast.next.next: 12 fast = fast.next.next 13 slow = slow.next 14 15 p, last = slow.next, None 16 while p: 17 temp = p.next 18 p.next = last 19 last = p 20 p = temp 21 22 p1, p2 = last, head 23 24 while p1 and p1.val == p2.val: 25 p1 = p1.next 26 p2 = p2.next 27 28 return p1 is None