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