[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?

问题:给定一个单向列表结构,判断它是不是回文的。

补充:是否可以在 O(n) 时间,O(1) 额外空间下完成?

解题思路:

对于数组,判断是否是回文很好办,只需要用两个指针,从两端往中间扫一下就可以判定。

对于单向列表,首先想到的是,将列表复制一份到数组中,然后用上面的方法就可以了,O(n) 时间, O(n)额外空间。

如果是 O(1)额外空间,就没有思路,在网上找了下,找到一个解决方案。值得注意的是,这个方案执行过程中,会改变原来列表的结构。

  • 利用快指针、慢指针定位列表的中间元素。快指针每次走两步,而慢指针每次只走一步,当快指针走到列表末尾,慢指针刚好在列表中间。
  • 根据慢指针,将列表前、后两半分开,并将后半列表翻转。
  • 对前半列表 和 翻转后的后半列表依次对比,判断原列表是否是回文的。
 1 bool isPalindrome(ListNode* head) {
 2     
 3     if(head == NULL || head->next == NULL){
 4         return true;
 5     }
 6     
 7     if(head->next->next == NULL){
 8         return (head->val == head->next->val);
 9     }
10     
11     if(head->next->next->next == NULL){
12         return (head->val == head->next->next->val);
13     }
14 
15     // 找列表中间元素
16     ListNode* slow = head;
17     ListNode* fast = head->next;
18     
19     while (slow != NULL && fast != NULL && fast->next != NULL) {
20         slow = slow->next;
21         fast = fast->next->next;
22     }
23     
24     // 翻转后半部分元素
25     ListNode* newHead = slow->next;
26     slow->next = NULL;
27     
28     ListNode* p = newHead->next;
29     ListNode* pNext = newHead->next->next;
30     
31     newHead->next = NULL;
32     while (pNext != NULL) {
33         p->next = newHead;
34         newHead = p;
35         p = pNext;
36         pNext = pNext->next;
37     }
38     
39     p->next = newHead;
40     newHead = p;
41 
42     // 判断是否是回文
43     ListNode* p1 = head;
44     ListNode* p2 = newHead;
45     
46     while (p2 != NULL) {
47         if (p1->val != p2->val) {
48             return false;
49         }
50         p1 = p1->next;
51         p2 = p2->next;
52     }
53     
54     return true;
55 }

 

posted @ 2015-12-23 00:04  TonyYPZhang  阅读(526)  评论(0编辑  收藏  举报