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

 

posted @ 2020-11-22 09:41  habibah_chang  阅读(91)  评论(0编辑  收藏  举报