234. Palindrome Linked List【easy】
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) { 13 return true; 14 } 15 16 ListNode * slow = head; 17 ListNode * fast = head; 18 19 while (fast->next != NULL && fast->next->next != NULL) { 20 slow = slow->next; 21 fast = fast->next->next; 22 } 23 24 slow->next = reverseList(slow->next); 25 slow = slow->next; 26 27 while (slow != NULL) { 28 if (head->val != slow->val) { 29 return false; 30 } 31 slow = slow->next; 32 head = head->next; 33 } 34 35 return true; 36 } 37 38 ListNode * reverseList(ListNode* head) 39 { 40 if (head == NULL) { 41 return NULL; 42 } 43 44 ListNode * pre = NULL; 45 while (head != NULL) { 46 ListNode * next = head->next; 47 head->next = pre; 48 pre = head; 49 head = next; 50 } 51 52 return pre; 53 } 54 55 };
关键点:
1、快慢指针找到中间位置
2、链表翻转
解法二:
1 class Solution { 2 public: 3 ListNode* temp; 4 bool isPalindrome(ListNode* head) { 5 temp = head; 6 return check(head); 7 } 8 9 bool check(ListNode* p) { 10 if (NULL == p) return true; 11 bool isPal = check(p->next) && (temp->val == p->val); 12 temp = temp->next; 13 return isPal; 14 } 15 };
递归,参考了@alex.tsitsura 的代码,就是利用了每一步递归的时候都有自己的栈空间的性质搞的。
一开始就是check(p->next)走到黑,然后就是到了最后一个节点了,我们比较一下最后一个节点和第一个节点的值;然后就执行下面的temp = temp->next,这个时候刚才那层递归也已经退栈了,现在我们的p对应的就是倒数第二个节点,temp对应的就是第二个节点;这样以此类推的搞下去,最后得解。
解法三:
上面的递归解法可能有些难以理解,可以改为如下:
1 class Solution { 2 public: 3 bool isPalindrome(ListNode* head) { 4 return check(head, head); 5 } 6 7 bool check(ListNode*& head, ListNode* p) { 8 if(!p) { return true; } 9 bool isPal = check(head, p->next); 10 if(head->val != p->val) { 11 return false; 12 } 13 head = head->next; 14 return isPal; 15 } 16 };
参考了@Meng-Ju 的代码