Javascript 如何在更短的时间内完成此问题?

Javascript 如何在更短的时间内完成此问题?,javascript,big-o,Javascript,Big O,编辑:因此我将代码更改为: function countTinyPairs(a, b, k) { let pairs = 0; let arr = []; b.reverse() for (num in a) { result = String(a[num]) + String(b[num]) if (result < k) { pairs++ } } return pa

编辑:因此我将代码更改为:

function countTinyPairs(a, b, k) {
    let pairs = 0;
    let arr = [];
    b.reverse()
    for (num in a) {
        result = String(a[num]) + String(b[num])
        if (result < k) {
            pairs++
        }
    }
    return pairs
}
它的工作原理完全相同,无需检查新的arr/push等。这会在更短的时间内运行吗?有没有办法检查一下自己需要多长时间

我正在做一个Codesignal javascript练习测试,现在已经完成了。我经历了一段非常艰难的时期,现在我知道我需要更多的练习,然后才能考虑做实际的测试。其中一个问题是:

给定两个长度相同的整数a和b数组,以及一个整数k。我们将从左到右遍历数组a,同时从右到左遍历数组b,并查看对x,y,其中x来自a,y来自b。如果串联xy严格小于k,则这种对称为极小

这就是我写的代码:

function countTinyPairs(a, b, k) {
    let pairs = 0;
    let arr = [];
    b.reverse()
    for (num in a) {
        for (num in b) {
            result = String(a[num]) + String(b[num])
            if (result < k) {
                if ((arr.findIndex(e => e === result)) === -1) {
                    arr.push(String(result));
                    pairs++
                }        
            }
        }
    }
    return pairs
}
它可以工作,但执行时间限制为4秒。有一个隐藏的测试用例,我的函数需要4秒以上的时间才能完成,我假设数组的数量非常多。我还没有学到任何关于大O或者它叫什么的东西,所以我对它一无所知

我猜在我自己成功解决这个问题之前,我必须先了解它?或者,我只是写了一些糟糕的代码,并且可以在不知道大O的情况下用更好的代码来完成吗?

给你两个相同长度的整数数组a和b。长度是相同的,所以我们只需要迭代一次,将其从^2改进到^2。您仍然需要检查每个元素,因此这是该问题的最佳复杂性

if语句检查重复项与变量对一样不需要。 您可以使用一个集合来检查重复项,最后返回其长度,而不是手动计算对数

我附上下面的示例解决方案:

常数countTinyPairs=a,b,k=>{ 常量集=新集; 对于设i=0,j=b.length-1;i if语句检查重复项与变量对一样不需要。 您可以使用一个集合来检查重复项,最后返回其长度,而不是手动计算对数

我附上下面的示例解决方案:

常数countTinyPairs=a,b,k=>{ 常量集=新集; 对于设i=0,j=b.length-1;iconsole.logcountTinyPairs[1,2,3,4,5],[1,2,3,4,5],40代码的复杂性在^2上

下面是我将如何解决它。我希望我的任务是正确的,请张贴一些输入/输出的例子

如果a和b的长度相等,则可以使用单个循环对其进行迭代。复杂度取决于其中n是a的长度

为什么要检查副本?这是要求吗

function test(a,b,k)
{
  let x,y,i,xy, result =[];
  for (i=0;i<a.length;i++)
  {
     x = a[i];
     y = b[b.length - 1 -i]
     xy = parseInt([x,y].join(''));
     if (xy < k) result.push(xy);
  }
  return result;
 }
 let a = [1,2,3,4,5], b=[4,5,6,7,8], k = 40;
 console.log(test(a,b,k));

 // Output: [18, 27, 36]

代码的复杂性在^2上

下面是我将如何解决它。我希望我的任务是正确的,请张贴一些输入/输出的例子

如果a和b的长度相等,则可以使用单个循环对其进行迭代。复杂度取决于其中n是a的长度

为什么要检查副本?这是要求吗

function test(a,b,k)
{
  let x,y,i,xy, result =[];
  for (i=0;i<a.length;i++)
  {
     x = a[i];
     y = b[b.length - 1 -i]
     xy = parseInt([x,y].join(''));
     if (xy < k) result.push(xy);
  }
  return result;
 }
 let a = [1,2,3,4,5], b=[4,5,6,7,8], k = 40;
 console.log(test(a,b,k));

 // Output: [18, 27, 36]

首先,不需要多个循环。你有三个:

b、 reverse将在适当的位置反转b,可能会增加复杂性。即使是奥隆,也没有必要。 for num在上迭代。 for num in b在上迭代b。但是,由于它是一个内部循环,因此总数为^2。 arr.findIndexe=>e==result将在找到的任何对上触发另一个Om迭代。取决于k的值,该值可能只有几倍或几倍。它已经在^2上,所以最坏的情况是k值很高,覆盖了每一对的组合,所以每次都会被触发,因此您将得到^3上的复杂性。 消除a和b上的多个循环 假设a和b的长度相等,我们可以用一个循环在两个数组上迭代。为了实现反向迭代,我们可以使用基本算法来获得b的索引,该索引与a的索引从开始到结束的距离相同。或者换句话说,您可以这样做,在两个方向上同时迭代两个数组:

常数a=[2,9,2]; 常数b=[5,3,5]; 对于let i=0;i} 首先,不需要多个循环。你有三个:

b、 reverse将在适当的位置反转b,可能会增加复杂性。即使是奥隆,也没有必要。 for num在上迭代。 for num in b在上迭代b。但是,由于它是一个内部循环,因此总数为^2。 arr.findIndexe=>e==result将在找到的任何对上触发另一个Om迭代。取决于k的值,该值可能只有几倍或几倍。它已经在^2上,所以最坏的情况是k值很高,覆盖了每一对的组合,所以每次都会被触发,因此您将得到^3上的复杂性。 消除a和b上的多个循环 假设a和b的长度相等,我们可以用一个循环在两个数组上迭代。为了实现反向迭代,我们可以使用基本算法来获得b的索引,该索引与a的索引从开始到结束的距离相同。或者换句话说,您可以这样做,在两个方向上同时迭代两个数组:

常数a=[2,9,2]; 常数b=[5,3,5]; 对于let i=0;i} 这个问题的措辞有些含糊不清,没有提供具体的投入和预期的产出也无济于事。以下是根据我对问题的理解编写解决方案的方法-

const countTinyPairs = (a, b, k) =>
  loop
    ( ( [ x, xs ] = likeList(a)
      , [ y, ys ] = likeList([...b].reverse())
      , pairs = 0
      ) =>
      x == null || y == null
        ? pairs
        : recur
            ( xs
            , ys
            , Number(`${x}${y}`) < k
                ? pairs + 1
                : pairs
            )
    )
使用我们自己的泛型函数loop、recur和likeList,我们可以大大减少推导答案所需的概念开销-

常数likeList=t=[],c=0=> {[Symbol.iterator]:=>[t[c],likeListt,c+1].values} const recur=…v=> {recur[Symbol.iterator]:=>v.values} 常量循环=f,…初始化=> {设r=f…init 而r&&r.recur===recur r=f…r 返回r } 如果您想了解更多关于这些助手的设计选择,我鼓励您查看

展开下面的代码段以运行程序并在您自己的浏览器中验证结果-

常数likeList=t=[],c=0=> {[Symbol.iterator]:=>[t[c],likeListt,c+1].values} const recur=…v=> {recur[Symbol.iterator]:=>v.values} 常量循环=f,…初始化=> {设r=f…init 而r&&r.recur===recur r=f…r 返回r } 常数countTinyPairs=a,b,k=> 环 [x,xs]=likeLista ,[y,ys]=likeList[…b]。相反 ,对=0 => x==null | | y==null ? 对 :重现 xs ,ys ,编号`${x}${y}`//3问题的措辞有些含糊不清,没有提供具体的投入和预期的产出也无济于事。以下是根据我对问题的理解编写解决方案的方法-

const countTinyPairs = (a, b, k) =>
  loop
    ( ( [ x, xs ] = likeList(a)
      , [ y, ys ] = likeList([...b].reverse())
      , pairs = 0
      ) =>
      x == null || y == null
        ? pairs
        : recur
            ( xs
            , ys
            , Number(`${x}${y}`) < k
                ? pairs + 1
                : pairs
            )
    )
使用我们自己的泛型函数loop、recur和likeList,我们可以大大减少推导答案所需的概念开销-

常数likeList=t=[],c=0=> {[Symbol.iterator]:=>[t[c],likeListt,c+1].values} const recur=…v=> {recur[Symbol.iterator]:=>v.values} 常量循环=f,…初始化=> {设r=f…init 而r&&r.recur===recur r=f…r 返回r } 如果您想了解更多关于这些助手的设计选择,我鼓励您查看

展开下面的代码段以运行程序并在您自己的浏览器中验证结果-

常数likeList=t=[],c=0=> {[Symbol.iterator]:=>[t[c],likeListt,c+1].values} const recur=…v=> {recur[Symbol.iterator]:=>v.values} 常量循环=f,…初始化=> {设r=f…init 而r&&r.recur===recur r=f…r 返回r } 常数countTinyPairs=a,b,k=> 环 [x,xs]=likeLista ,[y,ys]=likeList[…b]。相反 ,对=0 => x==null | | y==null ? 对 :重现 xs ,ys ,编号`${x}${y}`//3 a中的for num后跟b中的for num都使用相同的隐式全局变量。你确定这有效吗?假设长度是3,你在测试x1,y3,x1,y2,x1,y1,x2,y3,x2,y2,x2,y1,x3,y3,x3,y2,x3,y1。我理解这个练习的方式是,你应该只测试x1,y3,x2,y2,x3,y1,这需要一个for循环,从0到长度-1。这将从On*n移动到On。然而,同时通过数组b还不是很清楚,我可能是错的。是的,这是一段糟糕的代码,你不需要学习任何关于大O的知识就可以有效地解决问题。另外,我很确定你没有包括完整的描述。
您应该返回什么,小于目标值的串联值的数量,或者产生这种串联值的索引的数量?例如,在countTinyPairs[2,9,2],[5,3,5],30中,我们检查[25,93,25]`以查看每个值是否小于30。我们是返回1,因为25是唯一匹配的值,还是返回2,因为25在其中有两次?a中的for num后跟b中的for num都使用相同的隐式全局变量。你确定这有效吗?假设长度是3,你在测试x1,y3,x1,y2,x1,y1,x2,y3,x2,y2,x2,y1,x3,y3,x3,y2,x3,y1。我理解这个练习的方式是,你应该只测试x1,y3,x2,y2,x3,y1,这需要一个for循环,从0到长度-1。这将从On*n移动到On。然而,同时通过数组b还不是很清楚,我可能是错的。是的,这是一段糟糕的代码,你不需要学习任何关于大O的知识就可以有效地解决问题。另外,我很确定你没有包括完整的描述。您应该返回什么,小于目标值的串联值的数量,或者产生这种串联值的索引的数量?例如,在countTinyPairs[2,9,2],[5,3,5],30中,我们检查[25,93,25]`以查看每个值是否小于30。我们是返回1,因为25是唯一匹配的值,还是返回2,因为25在其中有两次?我在看到这个答案之前编辑了我的帖子,这个答案和我编辑的代码差不多。因此,如果我最初写这篇文章,它会在4秒的时间限制内工作吗?有没有一种方法可以让我自己运行测试时间?在你编辑的代码中,仍然有一个不必要的b部分。当涉及到检查它需要多长时间时,有一个方法。@ScottSauyet这是真的,但通过在编辑之前查看示例,我认为有必要检查重复项。@Cat请编辑描述以澄清是否需要它。您询问了如何查找函数的运行时。你可以使用和来记录函数的运行时间。我在看到这个答案之前编辑了我的帖子,这和我编辑的代码差不多。因此,如果我最初写这篇文章,它会在4秒的时间限制内工作吗?有没有一种方法可以让我自己运行测试时间?在你编辑的代码中,仍然有一个不必要的b部分。当涉及到检查它需要多长时间时,有一个方法。@ScottSauyet这是真的,但通过在编辑之前查看示例,我认为有必要检查重复项。@Cat请编辑描述以澄清是否需要它。您询问了如何查找函数的运行时。您可以使用和来记录函数的运行时间。