合并k个有序数组

给定K个有序数组,每个数组有n个元素,想把这些数组合并成一个有序数组

可以利用最小堆完成,时间复杂度是O(nklogk),具体过程如下:

创建一个大小为n*k的数组保存最后的结果
创建一个大小为k的最小堆,堆中元素为k个数组中的每个数组的第一个元素
重复下列步骤n*k次:
每次从堆中取出最小元素(堆顶元素),并将其存入输出数组中
用堆顶元素所在数组的下一元素将堆顶元素替换掉,
如果数组中元素被取光了,将堆顶元素替换为无穷大。每次替换堆顶元素后,重新调整堆
初始化最小堆的时间复杂度O(k),总共有kn次循环,每次循环调整最小堆的时间复杂度是O(logk),所以总的时间复杂度是O(knlogk)

代码如下,已测试通过:

import sys

class HeapNode:
    def __init__(self,x,y=0,z=0):
        self.value=x
        self.i=y
        self.j=z

def Min_Heap(heap):#构造一个堆,将堆中所有数据重新排序
    HeapSize = len(heap)#将堆的长度单独拿出来方便
    for i in range((HeapSize -2)//2,-1,-1):#从后往前出数
        Min_Heapify(heap,i)

def Min_Heapify(heap,root):
    heapsize=len(heap)
    MIN=root
    left=2*root+1
    right=left+1
    if left<heapsize and heap[MIN].value>heap[left].value:
        MIN=left
    if right <heapsize and heap[MIN].value>heap[right].value:
        MIN=right
    if MIN!=root:
        heap[MIN], heap[root] = heap[root], heap[MIN]
        Min_Heapify(heap, MIN)

def MergeKArray(nums,n):
    # 合并k个有序数组,每个数组长度都为k
    knums=[]
    output=[]
    for i in range(len(nums)):
        subnums=nums[i]
        knums.append(HeapNode(subnums[0],i,1))
        Min_Heap(knums)#k个元素初始化最小堆

    for i in range(len(nums)*n):
        # 取堆顶,存结果
        root=knums[0]
        output.append(root.value)
        #替换堆顶
        if root.j<n:
            root.value=nums[root.i][root.j]
            root.j+=1
        else:
            root.value=sys.maxsize
        knums[0]=root
        Min_Heapify(knums,0)
    return output

knums=[[1,2,3],[1,3,6],[4,5,8]]
print(MergeKArray(knums,3))

原文地址:https://www.cnblogs.com/tsdblogs/p/9848674.html

时间: 2024-10-18 12:12:27

合并k个有序数组的相关文章

合并两个有序数组a和b到c

1 // 合并两个有序数组a和b到c 2 void Merge_Array(int a[], int n, int b[], int m, int c[]) 3 { 4 int i, j, k; 5 i = j = k = 0; 6 while(i < n && j < m) 7 { 8 if(a[i] < b[j]) 9 c[k++] = a[i++]; 10 else 11 c[k++] = b[j++]; 12 } 13 while(i < n) 14 c[k

合并k个有序链表

题目: 合并k个有序链表,并将结果用一个有序链表输出 例如:输入: [   1->4->5,   1->3->4,   2->6 ] 输出: 1->1->2->3->4->4->5->6 思路: 假设k个链表的总元素数目为n.首先想到两两合并列表,在序列1和2合并,3和4合并,依次类推.直到合并的只剩一个链表.这种操作的时间复杂度为O(nlog(k)),空间复杂度为O(1).python代码如下: class Solution(obj

[leetcode] 88. 合并两个有序数组

88. 合并两个有序数组 水题,没有在原数组上做,偷了个懒 class Solution { public void merge(int[] nums1, int m, int[] nums2, int n) { int[] ans = new int[m + n]; int i = 0, j = 0; int top = 0; while (i < m && j < n) { if (nums1[i] < nums2[j]) { ans[top++] = nums1[i

合并两个有序数组

思路: 跟替换字符串中的空格一样,都是从后往前遍历.因为从前往后遍历的话,元素需要移动的次数较多. 示意图: 代码: /****************************************** 两个有序数组的合并 by Rowandjj 2014/7/16 ******************************************/ #include<iostream> using namespace std; #define MAX 1024 //合并有序数组a与有序数

高效合并两个有序数组(Merge Sorted Array)

Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note: You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2.The number of elements initi

小算法:合并两个有序数组,合并之后仍然有序

1 /** 2 * 合并两个有序数组,合并后仍然有序 3 * @param a 要合并的数组A 4 * @param b 要合并的数组B 5 * @param c 合并后的数组C 6 */ 7 public static void merge(int a[] ,int b[],int c[]){ 8 int lengthA = a.length; 9 int lengthB = b.length; 10 11 int indexA = 0; 12 int indexB = 0; 13 int i

两个有序数组合并成一个有序数组

两个有序数组合并成一个有序数组 1. 题目描述 数组a是有序的,数组b也是有序的,如何高效地合并它们成一个数组,并且新数组也是有序的? 2. 从后往前合并 这道题目是师兄电面阿里的时候,问到的一道题目.现在我们来说一下解法~ 假设数组a足够长,可以在数组a上合并二者.我们的解法基本思想就是从后往前合并数组. 每次合并的时候,都要比较a和b当前数组的大小,取较大的值后移,注意一定要是后移! 为什么从后往前呢?其实就是为了方便后移,因为较大的一定是在后面的. 程序如下: #include<iostr

[LeetCode] 23. Merge k Sorted Lists 合并k个有序链表

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 与21. Merge Two Sorted Lists的拓展,这道题要合并k个有序链表,还是可以两两合并. 类似题目: [LeetCode] 21. Merge Two Sorted Lists 合并有序链表 原文地址:https://www.cnblogs.com/lightwindy/p/8512

leetcode python 012 hard 合并k个有序链表

#[LeetCode] Merge k Sorted Lists 合并k个有序链表(升序) import numpy as npimport time class Node(object):    def __init__(self,n,next_node=None):        self.data=n        self.next=next_node    class linklist(object):    def __init__(self):        self.head=N