zoukankan      html  css  js  c++  java
  • 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 };
  • 相关阅读:
    Linux下的输入/输出重定向
    strcpy与strncpy的区别
    C++的函数重载
    gtest 学习二
    gtest 学习一
    char* wchar* char wchar转换
    iconv 编译不通过问题
    嵌入式常用库
    驱动编程class_create说明
    libiconv 交叉编译
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14018296.html
Copyright © 2011-2022 走看看