[C/C++]K路归并/合并k个有序数组/合并K个升序链表

1、合并k个有序数组

假定有k个有序数组,每个数组中含有n个元素,您的任务是将它们合并为单独的一个有序数组,该数组共有kn个元素。设计和实现 一个有效的分治算法解决k-路合并操作问题,并分析时间复杂度。

时间复杂度:O(nlogk)

代码:

#include <iostream>
#include <vector>
using namespace std;
vector<int> mergeTowArrays(vector<int>A,vector<int>B)
{
    vector<int>temp;
    temp.resize(A.size() + B.size());
    int index = 0, j = 0, i = 0;
    while (i < A.size() && j < B.size())
    {
        if (A[i] < B[j])
            temp[index++] = A[i++];
        else
            temp[index++] = B[j++];
    }
        while (i < A.size())
            temp[index++] = A[i++];
        while (j < B.size())
            temp[index++] = B[j++];
        return temp;
}
vector<int> kMergeSort(vector<vector<int>>A, int start, int end)
{
    if (start >= end)
        return A[start];
    int mid = start + (end - start) / 2;
    vector<int>Left = kMergeSort(A, start, mid);
    vector<int>Right = kMergeSort(A, mid + 1, end);
    return mergeTowArrays(Left, Right);
}
vector<int> mergeSortArrays(vector <vector<int>>A)
{
    vector<int>temp;
    if (A.empty() || A.size() == 0 || A[0].size() == 0)
        return temp;
    temp = kMergeSort(A, 0, A.size() - 1);
    return temp;
}

2、23. 合并K个升序链表

给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。

时间复杂度分析:K 条链表的总结点数是 N,平均每条链表有 N/K 个节点,因此合并两条链表的时间复杂度是 O(N/K)。从 K 条链表开始两两合并成 1 条链表,因此每条链表都会被合并 logK 次,因此 K 条链表会被合并 K * logK 次,因此总共的时间复杂度是 KlogKN/K 即 O(NlogK)。

示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

示例 2:
输入:lists = []
输出:[]

示例 3:
输入:lists = [[]]
输出:[]

提示:
k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i] 按 升序 排列
lists[i].length 的总和不超过 10^4


代码:

/**
 * 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:

    ListNode* mergeTwoList(ListNode* l1, ListNode* l2)
    {
        if(l1==nullptr)
            return l2;
        if(l2==nullptr)
            return l1;
        if(l1->val<l2->val)
        {
            l1->next=mergeTwoList(l1->next,l2);
            return l1;
        }
        
        l2->next=mergeTwoList(l1,l2->next);  //即 l2->val<l1->val
        return l2;        
    }

    ListNode* mergeK(vector<ListNode*>& lists, int start, int end)
    {
        
        if(start>=end)
            return lists[start];
        
        int mid=(start+end)/2;
        ListNode* l1=mergeK(lists,start,mid);
        ListNode* l2=mergeK(lists,mid+1,end);
        return  mergeTwoList( l1,  l2);
    }
	
	//主函数
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.size()==0)
            return nullptr;
        ListNode* root;
        root=mergeK(lists,0,lists.size()-1);
        return root;
    }
};

结果:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值