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

 

posted @ 2017-01-23 12:18  lettuan  阅读(140)  评论(0编辑  收藏  举报