LeetCode之Palindrome Linked List

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
 /*思路:爲了判斷鏈表是否爲迴文,需要對比鏈表中第一個、倒數第一個,第二個、倒數第二個
 節點...等的值。由於鏈表不支持隨機訪問,所以直接這樣做的時間複雜度爲O(n^2)。
 爲了獲得更好的時間複雜度方法,觀察上面步驟,第一個與倒數第一個,第二個與倒數第二個,
 等等,發現如果有個指針能夠倒着走,就能夠獲得O(n)的時間複雜度。所以,想法來了,直接將
 後半部分鏈表翻轉即可。方法步驟如下:
 1.找到鏈表的中間節點;
 2.翻轉後半部分的鏈表;
 3.對比前後半部分鏈表,判斷是否爲迴文;
 4.將鏈表恢復爲原樣,返回結果。*/
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(head == nullptr || head->next == nullptr) return true;
        //1.找到鏈表的中間結點
        ListNode *slow = head, *fast = head;
        while(fast->next != nullptr && fast->next->next != nullptr){
            fast = fast->next->next;
            slow = slow->next;
        }
        
        //2.將後半段的鏈表進行翻轉
        ListNode* qhead = slow->next;
        qhead = reverse(qhead);
        
        //3.對比前後半部分鏈表,判斷鏈表是否爲迴文
        bool res = true;
        while(qhead != nullptr){
            if(head->val != qhead->val) res = false;
            head = head->next;
            qhead = qhead->next;
        }
        
        //4.將後半部分鏈表恢復原樣
        qhead = reverse(qhead);
        slow->next = qhead;
        return res;
    }
    
    ListNode* reverse(ListNode* head){
        //函數功能:翻轉鏈表
        if(head == nullptr || head->next == nullptr) return head;
        ListNode node(-1);
        node.next = head;
        head = head->next;
        node.next->next = nullptr;
        while(head != nullptr){
            ListNode *p = head;
            head = head->next;
            p->next = node.next;
            node.next = p;
        }
        return node.next;
    }
};

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