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,原因未明,留坑。