[LeetCode] 鏈表反轉相關題目


暫時接觸到LeetCode上與鏈表反轉相關的題目一共有3道,在這篇博文里面總結一下。首先要講一下我一開始思考的誤區:鏈表的反轉,不是改變節點的位置,而是改變每一個節點next指針的指向。

下面直接看看LeetCode上的題目:

206. Reverse Linked List

這是一道最基本的鏈表反轉題目。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (head == NULL || head->next == NULL) return head;
        ListNode *p = head;
        ListNode *q = head->next;
        head->next = NULL;
        while (q) {
            ListNode *r = q->next;
            q->next = p;
            p = q;
            q = r;
        }
        return p;
    }
};

其實就是不斷地將當前訪問到的位置的next指針指向它前面的指針,這是最基本的操作了。

 

92. Reverse Linked List II

這道題目規定了要進行反轉的位置區間,比上一題加大了難度。我們要先添加一個頭指針,指向head節點(最后返回頭指針的next即可);然后一直往后訪問,一直到要反轉的節點的前一位停下來。

我們要記錄下兩個節點的位置:開始反轉位置的節點的前一位、開始反轉位置的節點。因為在反轉后,開始反轉的節點的前一個節點的next指針要指向反轉的最后一個節點,開始反轉的節點的next要指向反轉的最后一個節點的后一個節點。

然后進行與上面一題同樣的反轉即可。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        if (m == n) return head;
        ListNode *cur = new ListNode(0);
        cur->next = head;
        ListNode *copy = cur;
        for (int i = 0; i < m - 1; i++) {
            cur = cur->next;
        }
        ListNode *temp1 = cur, *temp2 = cur->next;
        cur = cur->next;
        ListNode *p = cur, *q = cur->next;
        for (int i = m; i < n; i++) {
            ListNode *r = q->next;
            q->next = p;
            p = q;
            q = r;
        }
        temp1->next = p;
        temp2->next = q;
        return copy->next; 
    }
};

 


234. Palindrome Linked List

這一題要求在O(n)的時間復雜度和O(1)的空間復雜度下,判斷一個鏈表是否回文鏈表。

我們可以利用一快一慢兩個指針同時前進,當快指針到鏈表的末尾(即不能往后走)時,慢指針就走到序列中間。(這里有一點值得注意,就是無論節點個數是奇數還是偶數,此時從慢指針指向的節點的后一個節點開始反轉就可以了)。反轉后,對鏈表的前半部分和后半部分逐個比較即可。

/**
 * 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) {
        ListNode *copy = head;
        if (head == NULL || head->next == NULL) return true;
        ListNode * slow = head, *fast = head;
        while (fast->next && fast->next->next) {
            slow = slow->next;
            fast = fast->next->next;
        }
        slow = slow->next;
        ListNode *p = slow;
        ListNode *q = slow->next;
        slow->next = NULL;
        while (q) {
            ListNode *r = q->next;
            q->next = p;
            p = q;
            q = r;
        }
        while (p) {
            if (p->val != copy->val) {
                return false;
            }
            p = p->next;
            copy = copy->next;
        }
        return true;
    }
};

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM