【问题标题】:I need to speed this up to pass a code fights test (javascript)我需要加快速度以通过代码战斗测试(javascript)
【发布时间】:2017-07-14 15:45:26
【问题描述】:

任务是获取一个数组并返回最早的副本,如果没有则返回 -1。我是这样写的:

function firstDuplicate(a) {
    let singles = [];

    for (let i = 0; i < a.length; i++) {

        if (singles.indexOf(a[i]) == -1) {
            singles.push(a[i]);
        }
        else {
            return a[i];
        }

    }

    return -1;
}

它通过了除隐藏速度测试之外的所有测试。有没有另一种方法可以在 JS 中更快地编写这个?我看到了一个使用集合而不是数组的 Java 解决方案,但我想坚持使用 JS。

【问题讨论】:

  • 使用散列(一个对象)而不是另一个数组来跟踪重复项。
  • 使用 js 对象,而不是数组。因为这是一个测验,所以不给你答案:)
  • 首先您应该了解array#indexOf 的工作原理。每次都会从起始位置搜索到结束位置。搜索在O(n) 中,速度很慢。有多种方法可以加快速度,它们都包括使用不同的策略/数据结构。更好的数据结构是HashSet(包含在O(1))、TreeSet(包含在O(log n))。坚持使用数组时更好的策略是搜索算法,如BinarySearch排序技术,如QuickSort。我确信 JS 中已经有一些实现。

标签: javascript arrays performance


【解决方案1】:

您也可以在 JavaScript 中使用 Set 来实现此目的:

function firstDuplicate(array) {
  const set = new Set()

  for (const value of array) {
    if (set.has(value)) {
      return value
    }

    set.add(value)
  }

  return -1
}

console.log(firstDuplicate(['a', 1, 'b', 2, 'c', 1, 2, 3]))

正如@Zabuza 所解释的那样,您的解决方案的问题是您使用了indexOf(),它将算法的时间复杂度从 O(n) 更改为 O(n2),因为每个indexOf() 都是 O(n)。

使用Set 代替Array 可以利用散列,通过使用has() 将重复项从O(n) 更改为O(1),从而改变您的查找时间,从而使算法恢复到O(n) 复杂度总体而言。

【讨论】:

  • 您可以解释为什么这样做更快的原因。对于初学者来说,这并不清楚。 Array#indexOf 使用的技术是什么,与 Set#has 的区别在哪里。我认为这也会对 OP 有所帮助。
  • 非常感谢您解释答案。我承认目前这有点过头了,但我明白你在说什么。我知道这与 indexOf 速度慢有关,但我不知道您甚至可以在 JS 中使用 Set()。直到现在我还没有听说过。再次感谢,我喜欢开始新的一天学习新事物!
【解决方案2】:

与其推送单曲,不如分配一个频率数组并在循环遍历原始数组时增加频率。 第一次频率为 2 时,您有最早的重复。

将数组第 i 个元素的频率增加 '1' 肯定会更快,然后推送一个数组,然后随时搜索它。

【讨论】:

  • 如果不使用 sort(),我不确定如何做到这一点,并且 sort 在这种情况下将不起作用。在不知道之前要测试的所有数字的情况下如何更新频率?我不是总是需要为此添加到数组中吗?
  • 您可以使用零值预初始化去频率数组,并在您遍历数组时添加一个。
【解决方案3】:

试试这个。在大型数组中没有重复项的情况下,它应该会给您更快的速度。

function firstDuplicate(a) {
    let singles = new Set(a);

    if(singles.size == a.length)
      return -1;

    let temp = [];


    for (let i = 0; i < a.length; i++) {

        if (temp.indexOf(a[i]) == -1) {
            temp.push(a[i]);
        }
        else {
            return a[i];
        }

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多