leetcode算法題--重排鏈表★

原題鏈接:https://leetcode-cn.com/problems/reorder-list/

1、map

void reorderList(ListNode* head) {
    map<int,ListNode*> map;
    ListNode *p=head;
    int n=0;
    while(p!=NULL){//使用map將鏈表順序存儲
        map[n]=p;
        p=p->next;
        n++;
    }
    for(int i=0,j=n-1;i<j;i++,j--){//每次取i+j==1+n的節點鏈接即可
        int pre=j-1;
        map[pre]->next=map[j]->next;
        map[j]->next=map[i]->next;
        map[i]->next=map[j];
    }
}

2、遞歸★★

void reorderList(ListNode* head) {
    if(head==NULL||head->next==NULL||head->next->next==NULL){
        return;
    }
    int len=0;
    ListNode *p=head;
    while(p!=NULL){//求出節點數
        len++;
        p=p->next;
    }
    reorderListHelper(head,len);
}

ListNode *reorderListHelper(ListNode *head,int len){
    if(len==1){
        ListNode *outTail=head->next;
        head->next=NULL;
        return outTail;
    }
    if(len==2){
        ListNode *outTail=head->next->next;
        head->next->next=NULL;
        return outTail;
    }
    ListNode *tail=reorderListHelper(head->next,len-2);//相當於快慢指針,當len==1時,總數爲奇數,head正好走到中點;當len==2時,總數爲偶數,head走到中間左邊的節點。
    ListNode *subHead=head->next;//子鏈表的頭結點
    head->next=tail;
    ListNode *outTail=tail->next;//上一層head對應的tail
    tail->next=subHead;
    return outTail;
}

在這裏插入圖片描述
3、雙鏈表

示例:

1 -> 2 -> 3 -> 4 -> 5 -> 6
第一步,將鏈表平均分成兩半
1 -> 2 -> 3
4 -> 5 -> 6
    
第二步,將第二個鏈表逆序
1 -> 2 -> 3
6 -> 5 -> 4
    
第三步,依次連接兩個鏈表
1 -> 6 -> 2 -> 5 -> 3 -> 4

代碼:

void reorderList(ListNode* head) {
    if(head==NULL||head->next==NULL) return;
    ListNode *p=head,*q=head;
    while(q->next!=NULL&&q->next->next!=NULL){//找到中點,如果總長度是偶數,p,q長度相同;如果總長度是奇數,p比q長一個
        p=p->next;
        q=q->next->next;
    }
    q=reverse(p->next);//分隔鏈表,並且將後半部分倒序
    p->next=NULL;
    p=head;
    while(q!=NULL){//再將兩個鏈表交錯合併
        ListNode *tmp=q->next;
        q->next=p->next;
        p->next=q;
        p=q->next;
        q=tmp;
    }
}

ListNode* reverse(ListNode* head){//遞歸倒序
    if(head->next==NULL) return head;
    ListNode* last=reverse(head->next);
    head->next->next=head;
    head->next=NULL;
    return last;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章