234. Palindrome Linked List
参考:labuladong
问题:
判断一个链表,是否为回文链表。
Example 1: Input: 1->2 Output: false Example 2: Input: 1->2->2->1 Output: true
解法:
解法一:Linked List Traverse 链表遍历(后序遍历)
pre_traverse(ListNode* head){ printf(head->val);//前序遍历 pre_traverse(head->next); } post_traverse(ListNode* head){ post_traverse(head->next); printf(head->val);//后序遍历 }
先递归到链表结尾,访问结尾节点
再往回依次遍历当前节点的前一个节点。
本问题中,
我们要判断回文序列,即判断首尾两边,向中间夹逼,依次相等即可。
因此,要利用链表后序遍历,
首先找到结尾节点right
与首节点left进行比较。
因此这里的left需要,
在递归底部开始回退弹栈的过程中,顺序遍历left=left->next
所以,我们令left作为外部全局变量,不随函数弹栈改变。
递归函数中要传递的信息:res
当前right和left的比较结果&&上次弹栈前的二者比较结果res
即:
res=(left->val==right->val)&&res
代码参考:
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode() : val(0), next(nullptr) {} 7 * ListNode(int x) : val(x), next(nullptr) {} 8 * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 * }; 10 */ 11 class Solution { 12 public: 13 ListNode* left; 14 bool isPalindrome(ListNode* head) { 15 left = head; 16 return traverse(head); 17 } 18 bool traverse(ListNode* right) { 19 bool res; 20 if(!right) return true; 21 res = traverse(right->next); 22 //post traverse 23 res = (left->val==right->val && res); 24 left = left->next; 25 return res; 26 } 27 };
解法二:Linked List Reverse 链表反转
首先使用快慢指针的方法,找到链表中间节点mid
(slow一次走一步,fast一次走两步)
这里⚠️ 注意,
- 若链表有奇数个节点:fast!=null, fast->next==null
- 这时,需要对比除去中间这一个节点之外,从中间到两边对比。
- 若链表有偶数个节点:fast==null,fast->next更不可能存在
- 这时,刚好slow所在节点为,链表节点对半分后,右边第一个节点。
然后,反转slow->链表结尾tail,返回反转后的头节点tail
从head和tail开始比对,依次next,比对。
代码参考:
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode() : val(0), next(nullptr) {} 7 * ListNode(int x) : val(x), next(nullptr) {} 8 * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 * }; 10 */ 11 class Solution { 12 public: 13 bool isPalindrome(ListNode* head) { 14 if(!head) return true; 15 ListNode* mid = findmid(head); 16 ListNode* left = head; 17 ListNode* right = reverse(mid); 18 while(right){ 19 if(left->val != right->val) { 20 return false; 21 } 22 left = left->next; 23 right = right->next; 24 } 25 return true; 26 } 27 ListNode* reverse(ListNode* a) { 28 ListNode* cur = a, *pre = nullptr; 29 while(cur) { 30 ListNode* nxt = cur->next; 31 cur->next = pre; 32 pre = cur; 33 cur = nxt; 34 } 35 return pre; 36 } 37 ListNode* findmid(ListNode* head) { 38 ListNode* slow, *fast; 39 slow = head; 40 fast = head; 41 while(fast && fast->next) { 42 slow = slow->next; 43 fast = fast->next->next; 44 } 45 if(fast) {//odd:1,3,5,7... nodes 46 return slow->next; 47 } else { 48 return slow; 49 } 50 } 51 };