23.Kの昇順リンクリストをマージする

ここに画像の説明を挿入
ここに画像の説明を挿入
1.ブルートフォース方式:各リンクリストをトラバースし、各ノードをベクトルに追加してから、ベクトルを並べ替えます。cmpの使用法は、戻り値が1の場合、交換がないことです。最後に、リンクリストをトラバースして、新しいリンクリストを作成します。重要な点は、最後のtmpの次をnullポインタとして設定することです。
配列はリンクリストの先頭に格納され、それぞれがリンクされているため、分割統治法:分割統治法:マージとソート、分割関数の記述、次にマージ関数の記述を行う必要があります。リストは順序付けられているため、ノードに分割すると、分割が完了したと見なされ、リンクリストは1つだけ順番に残ります(要素が1つだけの順序付き右と同じです)。左と右が等しい場合は、分割が完了し、lists [left]に戻ることを意味します。それ以外の場合、分割は言うまでもなく、2つの新しいリンクリストは、左マージ後の順序付きリンクリストと後の順序付きリンクリストです。右マージ。最後に、2つのリンクリストのマージの結果が返されます。したがって、l1とl2は、ノードへの分割によって返されるリンクリスト、またはマージされたリンクリストのいずれかであり、一方のリンクリストに分割すると、もう一方のリンクリストとマージされます。
マージ操作:1つのリンクリストが空の場合は、別のリストを返します。センチネルノードと前に進むtmpを定義します。次のステップは、2つの順序付けられたリンクリストをマージし、すべてを理解して、最後に次のセンチネルに戻ることです。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
    
    
public:
    /*static bool cmp(ListNode* a, ListNode* b){
        return a->val < b->val;//如果a<b就不交换
    }*/
    ListNode* merge(ListNode* l1, ListNode* l2){
    
    
        if(l1 == nullptr || l2==nullptr){
    
    
            return l1==nullptr ? l2:l1;
        }
        //如果用l1或者l2中较小的那个点直接赋值给head,而不是新建结点,可以省很多内存,那样的话head就不是哨兵了,就是名副其实的头结点
        ListNode* head = new ListNode(0);
        ListNode* tmp = head;
        while(l1!=nullptr && l2!=nullptr){
    
    
            if(l1->val <= l2->val){
    
    
                tmp->next = l1;
                l1 = l1->next;
            }
            else{
    
    
                tmp->next = l2;
                l2 = l2->next;
            }
            tmp = tmp->next;
        }
        tmp->next = l1==nullptr?l2:l1;
        return head->next;;
    }

    ListNode* qiefen(vector<ListNode*>& lists,int left, int right){
    
    
        //当左右相等,证明切分到一个元素了,也就是一条链表
        if(left == right) return lists[left];
        int mid = left + (right-left)/2;
        ListNode* l1 = qiefen(lists,left,mid);
        //切分返回的值是一条归并排序完成的链表或者单独一条链表,也就是left==right的情况,只有一条链表默认是有序的,就和一个元素一定有序一样
        //l1和l2是两条切分好的链表
        ListNode* l2 = qiefen(lists,mid+1,right);
        return merge(l1,l2);
    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {
    
    
        if(lists.size() == 0) return nullptr;
        //暴力
        /*vector<ListNode*> vec;
        for(auto it:lists){
            ListNode* cur = it;
            while(cur != nullptr){
                vec.push_back(cur);
                cur = cur->next;
            }
        }
        sort(vec.begin(),vec.end(),cmp);
        ListNode* h = new ListNode(0);
        ListNode* tmp = h;
        for(int i = 0; i < vec.size(); ++i){
            tmp->next = vec[i];
            tmp = tmp->next;
        }
        //最后一行是关键!!因为vec里的结点比如最大的结点5(也就是最后一个)的next不一定是null,会形成环
        tmp->next = nullptr;
        return h->next;*/

        //多路归并
        return qiefen(lists,0,lists.size()-1);
    }
};

おすすめ

転載: blog.csdn.net/J_avaSmallWhite/article/details/112798282