描述
请判断一个链表是否为回文链表。
示例 1:
示例 2:
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
来源:力扣(LeetCode)
链接:234. Palindrome Linked List
解题思路
本题的主要思路是采用快慢指针, 快指针一次走两步, 慢指针一次走一步, 这样当快指针走到链表结尾的时候,慢指针正好走到中间。然后将慢指针走过部分的链表进行反转,单链表的反转可以参考这一题206. Reverse Linked List.
在链表反转以后需要对原链表的奇偶性做一个判断,如果是奇数,在慢指针走过的那个中间元素就不需要进行判断,移动反转后的链表指针一位,然后进行逐个判断元素是否相等。
具体代码如下:
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
int getLength(struct ListNode* head) { int count = 0; while(head) { count++; head = head->next; } return count; }
bool isPalindrome(struct ListNode* head) { if(!head || !head->next) return true; if(head->next && !head->next->next) { if(head->val == head->next->val) return true; else return false; } int len = getLength(head); struct ListNode *slow, *fast; slow = head->next; fast = head->next->next; while(fast && fast->next) { slow = slow->next; fast = fast->next->next; } struct ListNode *firstHalfHead = NULL; while(head != slow) { struct ListNode *nextTmp = head->next; head->next = firstHalfHead; firstHalfHead = head; head = nextTmp; } if(len % 2 == 1) { slow = slow->next; } while(firstHalfHead && slow) { if(firstHalfHead->val != slow->val) { return false; } firstHalfHead = firstHalfHead->next; slow = slow->next; } return true; }
|