此JavaScript函数是否具有线性或二次时间复杂度?

时间:2019-03-26 17:57:01

标签: javascript algorithm performance time-complexity

我正在尝试通过Google访谈视频https://youtu.be/XKu_SEDAykw?t=1139来解决这个问题。

尽管他们说视频中它是线性的,但我不确定100%是否(以及为什么)整个解决方案是线性的而不是二次的?

由于find() / includes()方法嵌套在for循环中,因此我认为它的运行时为O(N * N)

但是find() / includes()正在搜索一次增长1步的数组,这让我认为运行时实际上只是O(N + N)吗?

这是我在JavaScript中解决方案的版本:

const findSum = (arr, val) => {
  let searchValues = [val - arr[0]];
  for (let i = 1; i < arr.length; i++) {
    let searchVal = val - arr[i];
    if (searchValues.includes(arr[i])) {
      return true;
    } else {
      searchValues.push(searchVal);
    }
  };
  return false;
};


我的工作方式:

  • i = 1时,searchValues.length = 0
  • i = 2时,searchValues.length = 1
  • i = 3时,searchValues.length = 2

这不是暗示线性运行时间为O(N +(N-1))吗?还是我错过了什么?!

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

是的,您的解决方案是二次方的,因为正如您所提到的,.includes遍历数组,for也遍历数组。但是,在采访中他们谈论了unordered_set的查找数组,这意味着可以将其实现为具有O(1)查找/插入时间的HashSet,从而使算法为O(n)(和O (n²)最坏,最坏的情况)。相当于JS的是Set

 const findSum = (arr, sum) =>
  arr.some((set => n => set.has(n) || !set.add(sum - n))(new Set));