在一个排序数组中合并多个预排序数组的最快方法

问题描述

我正在寻找将多个预先排序的数组合并为一个排序数组且没有重复项的最快方法

例如:

const arrays = [
    [15,30,35,40,45,50],[33,36,39,42,48],[37,38,41,42]
];

应该输出

[15,33,37,48,50]

实际上这些数组要大得多,所以我正在寻找一种快速方法来做到这一点。

这个问题是关于性能我知道它可以用 concatsortO(n log (n)) 但我正在寻找O(n)

解决方法

未经测试。我不认为我的代码是最佳的,但我目前没有看到更好的方法来解决这个问题。

进一步的小改进可能是:

  • 使用普通的 for 循环代替 Array.prototype.reduce
  • 移除达到“完成”状态的数组(而不是仅仅将它们标记为完成)

console.time("Creation of arrays");
const arrays = Array.from({ length: 1000 },(_,row) => {
  return Array.from({ length: 100000 },i) => row + i);
});
console.timeEnd("Creation of arrays");

const createMergedArray = (arrays) => {
  console.time("Creation of toProcess");
  const toProcess = arrays.map((array,row) => {
    return { done: false,row,column: 0,array };
  });
  console.timeEnd("Creation of toProcess");

  const merged = [];

  while (toProcess.some(({ done }) => !done)) {
    const scan = toProcess.reduce(
      (acc,item) => {
        if (!item.done) {
          if (item.array[item.column] < acc.minimum) {
            acc.minimum = item.array[item.column];
            acc.rows = [item.row];
          } else if (item.array[item.column] === acc.minimum) {
            acc.rows.push(item.row);
          }
        }
        return acc;
      },{ rows: [],minimum: Infinity }
    );

    merged.push(scan.minimum);

    scan.rows.forEach((row) => {
      const item = toProcess[row];
      while (item.array[item.column] === scan.minimum) {
        ++item.column;
      }
      item.done = item.array.length === item.column;
    });
  }

  return merged;
};

console.time("Merging");
const merged = createMergedArray(arrays);
console.timeEnd("Merging");

console.assert(
  merged.every((n,i,arr) => n > arr[i - 1] || 0 === i),"Unsorted or duplicates found"
);

您没有提到数组的大小,所以我使用了 1k 行和 100k 列。

如果您将数组 (number[][]) 传递给 createMergedArray,它应该给您:

  • 按升序排列的唯一数字数组
  • 了解此方法是否适用于您的数据规模

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...