帶你粗略瞭解C++回文鏈表

請判斷一個鏈表是否為回文鏈表。

示例 1:

輸入: 1->2

輸出: false

示例 2:

輸入: 1->2->2->1

輸出: true

思路

1.用快慢指針,快指針有兩步,慢指針走一步,快指針遇到終止位置時,慢指針就在鏈表中間位置

2.同時用pre記錄慢指針指向節點的前一個節點,用來分割鏈表

3.將鏈表分為前後均等兩部分,如果鏈表長度是奇數,那麼後半部分多一個節點

4.將後半部分反轉 ,得cur2,前半部分為cur1

5.按照cur1的長度,一次比較cur1和cur2的節點數值

在這裡插入圖片描述

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(head==nullptr||head->next==nullptr)
            return true;
        ListNode* fast=head; //快指針
        ListNode* slow=head; //慢指針,找到鏈表的中間位置
        ListNode* pre=head;  //慢指針的前一個指針,用來分割鏈表
        while(fast&&fast->next){  //循環條件是fast和fast的下一個節點是否都存在,不用寫fast!=nullptr&&fast->next!=nullptr,直接fast&&fast->next
            pre=slow;
            fast=fast->next->next;
            slow=slow->next;
            //per=slow; //這句不能放在這,這裡的slow是slow->next。隻能放在slow=slow->next的前面。  
        }
        pre->next=nullptr;  //分割鏈表。per是前半部分鏈表的最後一個節點,所以是per的下一個結點為空,不是per==nullptr
        ListNode* cur1=head; //前半部分的鏈表
        ListNode* cur2=reverse(slow);  //對後半部分的鏈表進行反轉,reverse(ListNode* slow)錯誤,調用不用寫類型ListNode*

        while(cur1){ //循環條件是cur是否為空
            if(cur1->val!=cur2->val)  // 若有一個不相等則返回false
                return false;
            cur1=cur1->next;   //  判斷下一個節點
            cur2=cur2->next;   //
        }
        return true;  //都等於則true
    }
        //反轉鏈表
        ListNode* reverse(ListNode* head){
            ListNode* temp; //保存cur的下一個節點,下一次要操作cur->next的節點
            ListNode* cur=head;
            ListNode* pre=nullptr;
            while(cur){
                temp=cur->next;
                cur->next=pre;
                pre=cur;
                cur=temp;
            }
            return pre;
        }
};

總結

本篇文章就到這裡瞭,希望能給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: