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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章