1. 程式人生 > 其它 >LeetCode反轉連結串列題目總結

LeetCode反轉連結串列題目總結

參考了遞迴反轉連結串列的一部分k個一組反轉連結串列

核心演算法在於反轉前N個連結串列的結點,有兩種實現方式。

迭代實現方式如下:

ListNode* Reverse(ListNode *head, int n) {
    ListNode *pre = nullptr;
    ListNode *cur = head;
    ListNode *nxt = head;
    for (int i = 0; i < n; i++) {
        nxt = cur->next;
        cur->next = pre;
        pre = cur;
        cur = nxt;
    }
    head->next = cur;
    return pre;
}

改變每個結點指標的指向,使其指向其前一個結點。

遞迴實現方式如下:

ListNode *successor = nullptr;
ListNode* Reverse(ListNode *head, int n) {
    if (1 == n) {
        successor = head->next;
        return head;
    }
    ListNode *last = Reverse(head->next, n - 1);
    head->next->next = head;
    head->next = successor;
    return last;
}

每次都將頭節點移動到已完成反轉的前N個結點的末端。

206. 反轉連結串列

遞迴法AC程式碼:

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (nullptr == head) return head;
        if (nullptr == head->next) {
            return head;
        }
        ListNode*last = reverseList(head->next);
        head->next->next = head;
        head->next = nullptr;
        return last;
    }
};

耗時4 ms

迭代法AC程式碼:

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *pre = nullptr;
        ListNode *cur = head;
        ListNode *nxt = head;
        while (nullptr != cur) {
            nxt = cur->next;
            cur->next = pre;
            pre = cur;
            cur = nxt;
        }
        return pre;
    }
};

耗時4 ms

92. 反轉連結串列II

純遞迴法AC程式碼:

class Solution {
    ListNode *successor = nullptr;
public:
    ListNode* reverseBetween(ListNode* head, int left, int right) {
        if (1 == left) {
            head = Reverse(head, right - left + 1);
            return head;
        }
        head->next = reverseBetween(head->next, left - 1, right - 1);
        return head;
    }
    // 反轉連結串列前n個結點
    ListNode* Reverse(ListNode* head, int n) {
        if (1 == n) {
            successor = head->next;
            return head;
        }
        ListNode *last = Reverse(head->next, n - 1);
        head->next->next = head;
        head->next = successor;
        return last;
    }
};

耗時0 ms

迭代法AC程式碼:

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int left, int right) {
        ListNode *dummy = new ListNode(-1);
        dummy->next = head;
        ListNode *p = dummy;
        for (int i = 1; i < left; i++) {
            p = p->next;
        }
        p->next = Reverse(p->next, right - left + 1);
        return dummy->next;

    }
    // 反轉連結串列前n個結點
    ListNode* Reverse(ListNode *head, int n) {
        ListNode *pre = nullptr;
        ListNode *cur = head;
        ListNode *nxt = head;
        for (int i = 0; i < n; i++) {
            nxt = cur->next;
            cur->next = pre;
            pre = cur;
            cur = nxt;
        }
        head->next = cur;
        return pre;
    }
};

耗時0 ms

25. K 個一組翻轉連結串列

純迭代法AC程式碼:

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode *dummy = new ListNode(-1);
        dummy->next = head;
        ListNode *p = dummy->next;
        ListNode *q = dummy;
        while (nullptr != p) {
            for (int i = 0; i < k; i++) {
                if (nullptr == p) return dummy->next;
                p = p->next;
            }
            ListNode *temp = q->next;
            q->next = Reverse(temp, k);
            temp->next = p;
            q = temp;
        }
        return dummy->next;

    }
    // 反轉連結串列前n個結點
    ListNode *Reverse(ListNode *head, int n) {
        ListNode *pre = nullptr;
        ListNode *cur = head;
        ListNode *nxt = head;
        for (int i = 0 ; i < n; i++) {
            nxt = cur->next;
            cur->next = pre;
            pre = cur;
            cur = nxt;
        }
        head->next = cur;
        return pre;
    }
};

耗時8 ms

純遞迴法AC程式碼:

class Solution {
    ListNode *successor = nullptr;
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode *p = head;
        for (int i = 0; i < k; i++) {
            if (nullptr == p) return head;
            p = p->next;
        }
        ListNode *last = Reverse(head, k);
        head->next = reverseKGroup(p, k);
        return last;
    }
    // 反轉連結串列前n個結點
    ListNode* Reverse(ListNode *head, int n) {
        if (1 == n) {
            successor = head->next;
            return head;
        }
        ListNode *last = Reverse(head->next, n - 1);
        head->next->next = head;
        head->next = successor;
        return last;
    }
};

耗時8 ms