Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何在O(n*logk)时间内对平均长度为K的n个排序列表进行排序?_Algorithm - Fatal编程技术网

Algorithm 如何在O(n*logk)时间内对平均长度为K的n个排序列表进行排序?

Algorithm 如何在O(n*logk)时间内对平均长度为K的n个排序列表进行排序?,algorithm,Algorithm,如何在O(n*logk)时间内对平均长度为K的n个排序列表进行排序?您可以调整合并排序来完成此工作。合并排序利用了将已排序的列表合并到新的排序列表的便利性 您可以调整合并排序来执行此任务。合并排序利用了将已排序的列表合并到新的排序列表的便利性 正如在对您的问题的评论中提到的,O(nlog(k))是不可能的,但是这里有两个算法可以有效地完成您的任务;这里有一个: 取每个列表的第一个元素 并创建一个堆(大小为k)。弹出 最小元素。从中查找数组 元素来了(假设它来了) 从清单一开始)。下一个 元素,并

如何在O(n*logk)时间内对平均长度为K的n个排序列表进行排序?

您可以调整合并排序来完成此工作。合并排序利用了将已排序的列表合并到新的排序列表的便利性

您可以调整合并排序来执行此任务。合并排序利用了将已排序的列表合并到新的排序列表的便利性

正如在对您的问题的评论中提到的,O(nlog(k))是不可能的,但是这里有两个算法可以有效地完成您的任务;这里有一个:

取每个列表的第一个元素 并创建一个堆(大小为k)。弹出 最小元素。从中查找数组 元素来了(假设它来了) 从清单一开始)。下一个 元素,并将其推入 堆对于中的每个元素 合并列表,我们花费了日志(k)时间。所以 时间复杂度为O(N*logk),其中 N是表中元素的总数 所有的K名单

-作者:


正如在对您的问题的评论中所提到的,O(nlog(k))是不可能的,但是这里有几个算法可以有效地完成您的任务;这里有一个:

取每个列表的第一个元素 并创建一个堆(大小为k)。弹出 最小元素。从中查找数组 元素来了(假设它来了) 从清单一开始)。下一个 元素,并将其推入 堆对于中的每个元素 合并列表,我们花费了日志(k)时间。所以 时间复杂度为O(N*logk),其中 N是表中元素的总数 所有的K名单

-作者:


合并排序是关键。假设N是要合并的元素总数,K是包含它们的容器数:

  • 将所有已排序的序列追加到单个向量中,但要记住追加它们的位置。更好的方法是,如果您按照第一个元素的值对它们进行排序,将加快下一篇文章的速度

  • 然后,您可以在适当的位置合并已排序序列对(如果您使用C++,则std::inplace\u merge)。每个合并都是Na+Nb,所以每个步骤都是N。您必须执行logK步骤


因此,NlogK

合并排序是关键。假设N是要合并的元素总数,K是包含它们的容器数:

  • 将所有已排序的序列追加到单个向量中,但要记住追加它们的位置。更好的方法是,如果您按照第一个元素的值对它们进行排序,将加快下一篇文章的速度

  • 然后,您可以在适当的位置合并已排序序列对(如果您使用C++,则std::inplace\u merge)。每个合并都是Na+Nb,所以每个步骤都是N。您必须执行logK步骤


因此,NlogK

我相信实现O(N*log(K))是可能的,但不是在最坏的情况下

考虑对这些列表进行排序:

{0,1,2,3,4,5,6,7,8,9,10},
{10,11,12,13,14,15,16,17,18,19,20},
{20,21,22,23,24,25,26,27,28,29,30}  
我的人脑可以轻松地对这些列表进行排序,而无需读取每个值,因此应该有一种算法可以做到这一点。我们需要合并,同时使用修改的二进制搜索来查找值的范围

在最坏的情况下,得到O(N*K),因为每个值都必须进行比较。例如:

{0,2,4,6,8},
{1,3,5,7,9}
这是我在Go中的解决方案,我只会在知道排序列表通常具有相对于K较小的重叠区域时使用:

// variation of binary search that finds largest
// value up to and including max
func findNext(a []int, imin int, vmax int) int {
    imax := len(a) - 1
    best := -1
    for imin <= imax {
        imid := imin + ((imax - imin) / 2)
        if a[imid] == vmax {
            return imid
        } else if a[imid] < vmax {
            best = imid
            imin = imid + 1
        } else {
            imax = imid - 1
        }
    }
    return best
}

func sortNSortedLists(in [][]int) []int {
    var out []int
    cursors := make([]int, len(in))
    for {
        // Find the array indices that have the smallest
        // and next to smallest value (may be same) at
        // their current cursor.
        minIdx1 := -1
        minIdx2 := -1
        minVal1 := math.MaxInt32
        minVal2 := math.MaxInt32
        for i, cursor := range cursors {
            if cursor >= len(in[i]) {
                continue
            }
            if in[i][cursor] < minVal1 {
                minIdx2 = minIdx1
                minVal2 = minVal1
                minIdx1 = i
                minVal1 = in[i][cursor]
            } else if in[i][cursor] < minVal2 {
                minIdx2 = i
                minVal2 = in[i][cursor]
            }
        }
        if minIdx1 == -1 {
            // no values
            break
        }
        if minIdx2 == -1 {
            // only one array has values, so append the
            // remainder of it to output
            out = append(out, in[minIdx1][cursors[minIdx1]:]...)
            break
        }

        // If inVal1 is smaller than inVal2,
        // append to output all values from minVal1 to minVal2 found in
        // the minIdx1 array, and update the cursor for the minIdx1 array.
        if minVal1 < minVal2 {
            firstCursor := cursors[minIdx1]
            lastCursor := findNext(in[minIdx1], firstCursor, minVal2)
            if lastCursor != -1 {
                out = append(out, in[minIdx1][firstCursor:lastCursor+1]...)
                cursors[minIdx1] = lastCursor+1
                continue
            }
        }
        // Append the single value to output
        out = append(out, minVal1)
        cursors[minIdx1]++
    }
    return out
}
//查找最大值的二进制搜索的变体
//最大值(含最大值)
func findNext(a[]int,imin int,vmax int)int{
imax:=len(a)-1
最佳:=-1
对于imin=len(in[i]){
持续
}
如果在[i][cursor]
我相信实现O(N*log(K))是可能的,但不是在最坏的情况下

考虑对这些列表进行排序:

{0,1,2,3,4,5,6,7,8,9,10},
{10,11,12,13,14,15,16,17,18,19,20},
{20,21,22,23,24,25,26,27,28,29,30}  
我的人脑可以轻松地对这些列表进行排序,而无需读取每个值,因此应该有一种算法可以做到这一点。我们需要合并,同时使用修改的二进制搜索来查找值的范围

在最坏的情况下,得到O(N*K),因为每个值都必须进行比较。例如:

{0,2,4,6,8},
{1,3,5,7,9}
这是我在Go中的解决方案,我只会在知道排序列表通常具有相对于K较小的重叠区域时使用:

// variation of binary search that finds largest
// value up to and including max
func findNext(a []int, imin int, vmax int) int {
    imax := len(a) - 1
    best := -1
    for imin <= imax {
        imid := imin + ((imax - imin) / 2)
        if a[imid] == vmax {
            return imid
        } else if a[imid] < vmax {
            best = imid
            imin = imid + 1
        } else {
            imax = imid - 1
        }
    }
    return best
}

func sortNSortedLists(in [][]int) []int {
    var out []int
    cursors := make([]int, len(in))
    for {
        // Find the array indices that have the smallest
        // and next to smallest value (may be same) at
        // their current cursor.
        minIdx1 := -1
        minIdx2 := -1
        minVal1 := math.MaxInt32
        minVal2 := math.MaxInt32
        for i, cursor := range cursors {
            if cursor >= len(in[i]) {
                continue
            }
            if in[i][cursor] < minVal1 {
                minIdx2 = minIdx1
                minVal2 = minVal1
                minIdx1 = i
                minVal1 = in[i][cursor]
            } else if in[i][cursor] < minVal2 {
                minIdx2 = i
                minVal2 = in[i][cursor]
            }
        }
        if minIdx1 == -1 {
            // no values
            break
        }
        if minIdx2 == -1 {
            // only one array has values, so append the
            // remainder of it to output
            out = append(out, in[minIdx1][cursors[minIdx1]:]...)
            break
        }

        // If inVal1 is smaller than inVal2,
        // append to output all values from minVal1 to minVal2 found in
        // the minIdx1 array, and update the cursor for the minIdx1 array.
        if minVal1 < minVal2 {
            firstCursor := cursors[minIdx1]
            lastCursor := findNext(in[minIdx1], firstCursor, minVal2)
            if lastCursor != -1 {
                out = append(out, in[minIdx1][firstCursor:lastCursor+1]...)
                cursors[minIdx1] = lastCursor+1
                continue
            }
        }
        // Append the single value to output
        out = append(out, minVal1)
        cursors[minIdx1]++
    }
    return out
}
//查找最大值的二进制搜索的变体
//最大值(含最大值)
func findNext(a[]int,imin int,vmax int)int{
imax:=len(a)-1
最佳:=-1
对于imin=len(in[i]){
持续
}
如果在[i][cursor]