反轉鏈表2 leetcode

92. 反轉鏈表 II

難度中等325

反轉從位置 m 到 n 的鏈表。請使用一趟掃描完成反轉。

說明:
1 ≤ m ≤ n ≤ 鏈表長度。

示例:

輸入: 1->2->3->4->5->NULL, m = 2, n = 4
輸出: 1->4->3->2->5->NULL

步驟:

1.創建一個空節點res,將head置與其後面

2.記錄反轉區間的第一個節點和其前一個節點 1 2

3. 對反轉區間的元素進行反轉

4.將反轉後剩下的的節點(4 5)與步驟2的兩個節點連接

5.返回res.next(存res的目的是實現在head也被反轉的情況下也可以從頭輸出)

/**
 * 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) {
        ListNode* p=new ListNode(0);
        p->next=head; 
        ListNode* res=p;
        for(int i=0;i<m-1;i++){
            p=p->next;
        }
        //兩個連接處的節點
        ListNode* x1=p;//1
        ListNode* x2=p->next;//2
        int count=n-m;
        ListNode* pre=x2;//2
        ListNode* cur=x2->next;//3
        while(count--){
            ListNode* nex=cur->next;
            cur->next=pre;
            pre=cur;
            cur=nex;
        }//pre 4 cur 5
        x1->next=pre;//1 4
        x2->next=cur;//2 5
        return res->next;
    }
};

遞歸解決辦法:

class Solution {
public:
    ListNode* reverse(ListNode* x,ListNode* y){
        if(!y)
            return x;
        ListNode* nex=y->next;
        y->next=x;
        return reverse(y,nex);
    }
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        ListNode* res=new ListNode(0);
        ListNode* p=res;
        p->next=head;
        for(int i=0;i<m-1;i++){
            p=p->next;
        }
        ListNode* x=p;//1
        ListNode* st=p->next;//2
        for(int i=1;i<=n-m+1;i++){
            p=p->next;
        }//p 4
        ListNode* ed=p;//4
        ListNode* y=p->next;//5
        ed->next=NULL;
        x->next=reverse(NULL,st);//1 4
        st->next=y;//2 5
        return res->next;
    }
};

 

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