leetcode -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?
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 bool isPalindrome(ListNode* head) { 12 if(head == NULL || head->next == NULL) return true; 13 if(head->next->next == NULL){ 14 if(head->val == head->next->val) return true; 15 else return false; 16 } 17 ListNode* tp1 = head; 18 ListNode* tp2 = head; 19 while(tp2->next != NULL && tp2->next->next != NULL){ 20 tp1 = tp1->next; 21 tp2 = tp2->next->next; 22 } 23 ListNode* mid = tp1->next; 24 ListNode* p1 = head; 25 ListNode* p2 = reverse(mid); 26 while(p2 != NULL){ 27 if(p2->val != p1->val) return false; 28 else{ 29 p1 = p1->next; 30 p2 = p2->next; 31 } 32 } 33 return true; 34 } 35 ListNode* reverse(ListNode* mid){ 36 if(mid->next == NULL) return mid; 37 ListNode* now = mid; 38 ListNode* prev = NULL; 39 while(now != NULL){ 40 ListNode* tp = now->next; 41 now->next = prev; 42 prev = now; 43 now = tp; 44 } 45 return prev; 46 } 47 };
两种方法,一种是找到中间节点,然后将后面的数据存入vector,然后依次比较,空间复杂度为O(n);
另一种是找到中间节点,然后将后面的链表逆置,然后依次比较,空间复杂度为O(1)。
注意找中间节点用了两个指针,一个一次走一下,另一个一次走两下,这样最后一个到达结尾或者倒数第二的时候,前面的指针正好指向前一半的末尾或者中间节点(与奇偶有关)。这样就可以找到后一半的起始位置了。
然后对后一半进行逆置。这里采用了三个指针,分别指向前一个节点,当前节点和后一个节点,每次,将当前节点的next指针指向前一个节点,然后更新三个指针。直到当前节点为NULL(末尾),则此时前一个节点就是头结点。建议画图更形象地理解。
leetcode -Palindrome Linked List
原文:http://www.cnblogs.com/shnj/p/4645455.html