码迷,mamicode.com
首页 > 其他好文 > 详细

[LeetCode]#234 Palindrome Linked List

时间:2015-08-12 12:57:47      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:

一、题目

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?

 

二、解析

这个还是一个回文题目,是在做完回文数字后做的。这题要判断一个链表是不是满足回文条件。

难点就在O(1),我们不能用任何形式去保存链表中的元素。最开始我想了好几种方法都不符合这个要求,比如最简单的用栈、用list,甚至将链表尾巴连到头判断头尾是否相等,这些都避免不了O(n)的空间复杂度。

和喵爷讨论,他提出了反转链表的做法。百度了一下,还真是个挺常见的数据结构操作,自己试着写了一下,思路如下:

  1.首先遍历链表,得到链表长度,从而得到中点,效果:》》》》》

  2.从头开始,到中点结束,反转链表,效果:《《》》》

  3.从中点开始,根据奇偶情况,一个向左遍历链表,一个向右遍历链表,判断左右是否相等。

  最终时间复杂度O(3n) = O(n),空间复杂度只用到了少许变量来做反转,所以是O(1)的

 

三、代码

 1 # Definition for singly-linked list.
 2 # class ListNode:
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.next = None
 6 
 7 class Solution:
 8     # @param {ListNode} head
 9     # @return {boolean}
10     def isPalindrome(self, head):
11         start = p = q = r = ListNode(0)
12         start = p = head
13         length = 0
14         isOne = False
15         
16         #special cases
17         if head == None:
18             return True
19         
20         else:
21             #get the length
22             while head:
23                 length += 1
24                 head = head.next
25             head = start
26             
27             #special cases
28             if length == 1:
29                 return True
30             elif length == 2:
31                 if head.val == head.next.val:
32                     return True
33                 else:
34                     return False
35             else:
36                 pos = 0
37                 if length % 2 == 1:
38                     isOne = True
39                     pos = length / 2
40                     
41                 else:
42                     isOne = False
43                     pos = length / 2 - 1
44                 
45                 #reverse the linklist to the mid
46                 count = 0
47                 q = p.next
48                 while count < pos:
49                     r = q.next #p3 = p2.next
50                     q.next = p #p2.next = p1
51                     p = q      #p1 = p2
52                     q = r      #p2 = p3
53                     count += 1
54                 
55                 #check two linklist, which p is z-a and q is a-z
56                 _count = 0
57                 
58                 #偶数,acbbca类型,
59                 if isOne == False:
60                     while _count <= count and q:
61                         if p.val == q.val:
62                             p = p.next
63                             q = q.next
64                             _count += 1
65                         else:
66                             return False
67                     return True
68                 
69                 #总长为奇数,为acbca类型,p=q=
70                 else:
71                     p = p.next
72                     print !!
73                     while _count <= count and q:
74                         if p.val == q.val:
75                             p = p.next
76                             q = q.next
77                             _count += 1
78                         else:
79                             return False
80                     return True

 

四、总结

1.在写反转的时候,最开始写错了。

#正确:
count = 0
q = p.next
while count < pos:
      r = q.next
      q.next = p
   p = q q
= r count += 1 #错误: count = 0 while count < pos: q = p.next r = q.next q.next = p
p = q q
= r count += 1

错误的原因是q=p.next,最开始我把这句写进了whle循环里,这会出现什么情况呢?这里分析一下我的错误做法:

  假设一个链表:【1>>2>>3】,这里p=1

  反转开始,首先q=p.next=2, r=q.next=3,起到保存下指针的目的

  然后q.next=p,就完成了2的下一个指向了,即:【1<=>2  3】。

  然后p = q = 2, q = r = 3,循环就接着往后走了

  当下一次while循环的时候,q=p.next,会发生什么事情呢?我们看【1<=>2 3】,p=2, q=3, 但是q = p.next = 2.next = 1,这样一来q就从3变成了1,然后q.next=p = 1.next=2, 所以这时q=1, p=2。那再次循环呢,p=1, q=2,所以p,q就一直在互换位置,原因就出在p.next不应该被调用。

找到了bug,p.next惹的祸,把他从while循环中提出来

  还是这个链表【1>>2>>3】,这里p=1, q=2, r=3

  反转开始,q.next = p,完成了反转【1<=>2 3】,然后p=q=2, q=r=3

  再次循环,r=q.next=3.next = 4, q.next = 3.next = p = 2, p=q=3, q=r=4,【1<=>2<=>3, 4】,完成了2,3反转。p=3, q=4

可以看到,这里忽略了p.next不处理。

 

[LeetCode]#234 Palindrome Linked List

标签:

原文地址:http://www.cnblogs.com/breada/p/4723864.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!