leetcode92_翻轉鏈表||_遞歸

一. 遞歸

1. 參考這個作者寫的太好了,包括解決反轉鏈表的所有思路.

作者:labuladong
鏈接:https://leetcode-cn.com/problems/reverse-linked-list-ii/solution/bu-bu-chai-jie-ru-he-di-gui-di-fan-zhuan-lian-biao/

2. 這題是反轉m到n區間的鏈表,如果將head移動到m=1的位置,則變成反轉前n-m+1個節點,所以關鍵是把這個遞歸寫好.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    //記錄第一個節點反轉後應該連接哪個節點,
    //因爲此時的節點反轉後不一定指向NULL了
    ListNode* post = NULL;
    ListNode* reverseN(ListNode* head, int n) {
        //如果n==1,說明不需要反轉,此時直接返回head,
        //並且記錄反轉後應該連接哪個節點.
        if(n==1) {
            post = head->next;
            return head;
        }
        //對於head->next來說,只需要反轉前n-1個節點就夠了.
        ListNode* last = reverseN(head->next, n-1);
        head->next->next = head;
        //讓反轉後的head和應該連接的之後的點相連接.
        head->next = post;
        //返回反轉後的頭結點.
        return last;
    }
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        //如果m=1, 說明就和反轉前n個節點沒有區別了.
        if(m==1) return reverseN(head, n);
        //head需要連接以head->next爲節點,m-1和n-1爲區間的節點.
        head->next = reverseBetween(head->next,m-1,n-1);
        return head;
    }
};

二. 迭代

1. 迭代一般思路都很直接.

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        ListNode* dummy = new ListNode(0);
        dummy->next = head;
        //pre找到m節點的前一個,作爲連接點.
        ListNode* pre = dummy;
        for(int i=0;i<m-1;i++) {
            pre = pre->next;
        }
        ListNode* cur = pre->next;
        ListNode* post = NULL;
        ListNode* tmp = cur;
        //將m到n的區間進行反轉.
        for(int i=0;i<n-m+1;i++) {
            ListNode* next = cur->next;
            cur->next = post;
            post = cur;
            cur = next; 
        }
        //最後連接前面和和後面的鏈表.
        pre->next = post;
        tmp->next = cur;
        return dummy->next;
    }
};

發佈了95 篇原創文章 · 獲贊 26 · 訪問量 2135
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章