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;ifunction 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
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}`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}`您应该返回什么,小于目标值的串联值的数量,或者产生这种串联值的索引的数量?例如,在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请编辑描述以澄清是否需要它。您询问了如何查找函数的运行时。您可以使用和来记录函数的运行时间。