LeetCode:234. 迴文鏈表

一、問題描述

請判斷一個鏈表是否爲迴文鏈表。

示例 1:

輸入: 1->2
輸出: false

示例 2:

輸入: 1->2->2->1
輸出: true

二、解題思路

將鏈表分爲兩段,並且把後面一段進行倒置,然後再比較前後兩段是否相同即可。最簡單的方法就是先計算鏈表的長度,然後將前面一半用頭插法的辦法進行倒置,最後再比較,但是由於需要的是一半這個特殊的位置,所以我們可以考慮快慢指針,何謂快慢指針,其實就是兩個指針,一根指針一次移動一個位置,另一個指針一次移動兩個位置。快慢指針適合用於有中點相關的場景(有中點或倍數的時候可以考慮快慢指針來解決問題)

三、代碼實現

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if (!head || !head->next) return true;    
       
        ListNode *slow = head, *fast = head;
        while (fast && fast->next) //快慢指針法,讓slow指向鏈表中部位置
        {
            slow = slow->next;
            fast = fast->next->next;
        }
        //退出時,fast爲最後一個結點或者null,slow處在中間位置
        //與結點數有關,左子鏈表head~slow-1, 右子鏈表爲slow~end
        //右子鏈表比左子鏈表長一或者相等)
        //例:0~10,slow 5, fast 10; 0~9,slow5,fast null (0表示頭結點,slow和fast的起點)
       
        ListNode* right = reverseList(slow);//反轉右邊鏈表
        ListNode* left = head;
       
        while(left && right)//比較左右子鏈表是否相等
        {
            if(left->val == right->val)
            {
                left = left->next;
                right = right->next;
            }
            else
                return false;
           
        }
        return true;
    }
private:
    ListNode* reverseList(ListNode* head) {
        //pre永遠指向null,相當於一個尾節點
        ListNode* pre = NULL;
        ListNode* cur = head;
        while(cur != NULL){
            //next用來保存下一個節點。因爲會把當前節點cur拿下來,賦值給pre
            ListNode* next = cur->next;
            cur->next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章