LeetCode 234. Palindrome Linked List

 

 1 class Solution {
 2 public:
 3     bool isPalindrome(ListNode* head) {
 4         if(!head || head->next == NULL) return true;
 5         ListNode* tmp = head;
 6         int len = 0;
 7         while(tmp != NULL){
 8             tmp = tmp->next;
 9             ++len;
10         }
11         stack<int> data;
12         tmp = head;
13         for(int i = 0; i < len/2; ++i){
14             data.push(tmp->val);
15             tmp = tmp->next;
16         }
17         if(len % 2) tmp = tmp->next;
18         for(int i = len/2 + len % 2; i < len; ++i){
19             if(tmp->val != data.top()) return false;
20             data.pop();
21             tmp = tmp->next;
22         }
23         return true;
24     }
25 };

最简单的思路,遍历一遍链表得到长度,将前半段放入栈中,再与后半段比较。时间和空间均为O(n)。

 

时间O(n),空间O(1):

 1 class Solution {
 2 public:
 3     ListNode* getMid(ListNode* head){
 4         ListNode* fast = head, * slow = head;
 5         while(fast->next && fast->next->next){
 6             slow = slow->next;
 7             fast = fast->next->next;
 8         }
 9         // delete fast;不注释掉就RA
10         return slow;
11     }
12     
13     ListNode* inverseList(ListNode* head){
14         ListNode* p = NULL, * cur = head;
15         while(cur){
16             ListNode* tmp = cur->next;
17             cur->next = p;
18             p = cur;
19             cur = tmp;
20         }
21         return p;
22     }
23     bool isPalindrome(ListNode* head) {
24         if(!head || head->next == NULL) return true;
25         ListNode* mid = getMid(head);
26         ListNode* newmid = inverseList(mid->next);
27         while(newmid){
28             if(head->val != newmid->val) return false;
29             head = head->next;
30             newmid = newmid->next;
31         }
32         return true;
33     }
34 };

思路:翻转后半部分的链表,然后前半部分和后半部分一一进行比较。

具体实现:

getMid函数中,fast一次走2步,slow一次走1步,因此假设全长len,len偶时,slow到达前半段的最后一个节点,len奇时,slow到达正中间的节点,两种情况中,slow->next均为后半段的起始节点。

然后inverseList将后半段链表颠倒过来,p存放cur的原上一个节点,也即颠倒后的下一个节点,tmp存放cur的原下一个节点。先把cur下一个节点赋给tmp,再把cur->next改为p,然后p和cur各向后移动一步。

调用完这两个函数后,head为链表头节点,newmid为后半段头节点,开始比较。

 

delete fast会导致RE,原因未明,留坑。

 

posted @ 2016-03-13 23:16  co0oder  阅读(200)  评论(0编辑  收藏  举报