【问题标题】:Merging two sorted arrays into a third one can be done in O(n)?将两个排序数组合并到第三个数组可以在 O(n) 中完成吗?
【发布时间】:2012-05-10 17:45:06
【问题描述】:

我正在尝试将已排序的数组合并到第三个已排序的数组中,但我看不到 在O(n) 中可以做到这一点,仅在O(n*n) 中。我错了吗? O(n) 有没有办法做到这一点?

编辑:

其实问题有点不同:

我有 2 个已排序的跳过列表,我想将它们合并到一个新的已排序跳过列表中,而无需更改 输入(即两个跳过列表)。

我在想:

  • 将列表放在两个数组中

  • 使用 MergeSort 合并两个数组(这需要 O(n) 运行时)

  • 从排序后的数组中构建一个新的跳过列表 .... // 我不确定它的运行时间

有什么想法吗?

问候

【问题讨论】:

  • 不,我的作业问题之一。
  • 你真的应该尝试自己解决这个问题。这是许多算法/数据结构中的一项重要且基本的技术,值得您努力深入理解它。仅仅寻找解决方案并寻求帮助会破坏做功课的意义,并且会使您相互依赖且资源不足。

标签: arrays algorithm sorting merge


【解决方案1】:

您保持两个循环运行,并在将每个“边”中的值拉入第三个数组时在每个循环之间翻转。如果 arr1 的值小于当前的 arr2,则将 arr1 的值填充到 arr3 直到达到相等或“更大”,然后翻转过程并开始从 arr2 中提取值。然后继续来回弹跳,直到两个源数组中都没有剩下任何东西。

结果为 O(n+m),也就是 O(n)。

【讨论】:

    【解决方案2】:

    画出两个相互重叠的数组:

    list1=[1,2,6,10]

    list2=[3,4,10]

    如果我们从左边开始,向右移动,比较项目,每次我们取最小值并将其放入第三个数组。从我们取出最小项的列表中,我们移至下一项。

    i=0,j=0
    list1[i] < list2[j]
    take 1
    i+=1
    2<3
    take 2
    i+=1
    3<6
    take 3
    j+=1
    

    等等。

    直到我们得到最终的合并数组 [1,2,3,..]

    因为为第三个数组选择每个元素只需要一步,基本上是 O(N)。

    【讨论】:

      【解决方案3】:

      您可以为已经排序的数组使用两个索引变量,为正在排序的数组使用另一个索引变量,全部初始化为 0。 现在,虽然您还没有到达任何排序数组的末尾,但在每次迭代中比较两个指向的值,取更高(或更低,取决于您的排序)值并增加指向您的值的索引刚用过。

      最后,遍历您尚未完成的数组,然后将剩余的值粘贴到合并的数组中。

      这样,您只需遍历一次值,即 O(n)。

      【讨论】:

        【解决方案4】:

        提示:只考虑两个列表的头元素(并在处理时[虚拟地]删除它们)。

        【讨论】:

          【解决方案5】:

          如果两个输入列表都已排序,那么合并怎么可能是 O(n*n)?自己给的算法(3个步骤)肯定是O(n)而不是O(n*n)。每一步都是O(n),所以总体来说是O(n)。 big-O 由算法的最高阶决定。在做作业之前一定要了解大 O 的概念。

          【讨论】:

            【解决方案6】:

            是的,可以做到,实际上是 O(n + m) 其中 n 和 m 是第一个和第二个数组的长度,连续。

            算法称为一次合并

            伪代码:

            i, j, k = 0 // k is index for resulting array
            //maximum length of the resulting array can be n+m, 
            //so it is always safe to malloc for such a length if you are in C or C++
            
            while(i< len(array1) and j < len(array2) )
                 if (array1[i] == array2[j])
                       result[k] = array1[i]
                       ++i, ++j, ++k
                 else if (array1[i] < array2[j])
                       result[k] = array1[i]
                       ++i, ++k
                 else
                       result[k] = array2[j] 
                       ++j, ++k
            
            //now one array might not be traversed all the way up
            if ( i < len(array1) )
                  while( i != len(array1))
                        result[k] =  array1[i]
                        ++i, ++k
            
            else if ( j < len(array2) )
                  while( j != len(array2) )
                        result[k] = array2[j]
                        ++j, ++k
            

            基本上,您同时遍历两个数组,如果长度不同,则不会一直向上遍历较大的数组,因此您只需将较大数组的所有元素添加到 结果中。

            【讨论】:

              猜你喜欢
              • 2019-08-17
              • 2017-02-20
              • 1970-01-01
              • 2016-05-18
              • 1970-01-01
              • 1970-01-01
              • 2016-10-22
              • 2022-01-16
              • 2014-08-02
              相关资源
              最近更新 更多