我对此Kata(斐波那契数列的第n个值)有一个有效的解决方案,但是我不断收到超时错误。谁能提供有关如何重构它以使其更有效运行的建议?提前致谢!
以下是带有说明的链接-https://www.codewars.com/kata/simple-fun-number-395-fibonacci-digit-sequence/train/javascript
为您提供了三个非负整数a,b和n,并且使它们像fibonacci序列一样构成无限序列,请使用以下规则:
第一步:使用ab作为初始序列。 步骤2:计算 序列的最后两位数字,并将其附加到序列的末尾。 重复步骤2 您的任务是完成功能查找。 返回序列的第n个数字(从0开始)。
function find(a,b,n){
let start = ("" + a + b);
let next = a + b;
let seq = start + next;
while (seq.length <= n) {
seq += (parseInt(seq[seq.length-2]) + parseInt(seq[seq.length-1]));
}
return parseInt(seq[n]);
}
console.log(find(7,8,9))
// should return 5
答案 0 :(得分:2)
首先。 。 。不要使用字符串,不要使用parseInt
,不要一次保留整个序列。您只需要数字,并且只需要后两位。给定一个介于10到18之间的数字x
(这是两位数的最大和),其十位数为1
,而其位数为x - 10
。仅此一项将是一项重大改进。
第二。 。 。由于给定点之后的整个序列由该点的前两位数字 1 确定,并且只有100个可能的两位数字序列,因此每个序列都必须在200位数字内重复。也就是说,最多200个数字之内,它必然会进入一个循环的循环,它永远不会消失,循环长度小于200个数字。 2 因此,如果n
大于数百,您可以通过查找此循环的长度并“跳过”该长度的较大倍数来进行大规模优化。
1。实际上,这并非如写的那样正确。例如,序列69156…和79167…bot包含91,但是后面跟着不同的东西。这是因为'1'属于两位数字,都是,其数字由前两位数字确定。我不确定如何更好地表达这一点,但希望您明白我的意思。它不会影响整体论点,但是在应用该想法时需要谨慎。
2。实际上少得多;测试 a 和 b 的所有可能值,我发现该序列始终进入循环,仅用25位数字就完成了其第一次迭代!但是除了穷举测试之外,我不确定如何严格证明这个小得多的数字。因此以一种依赖于它的方式编写代码可能是作弊的。
答案 1 :(得分:1)
在进行转换和字符串操作时,通常速度较慢。
function nextVal(num){
const last = (num%10);
const lastButOne = (num - last)/10 % 10;
const sum = last + lastButOne;
return sum < 10 ? num * 10 + sum : num *100 + sum;
}
function find(a,b,n){
let num = a * 10 + b;
const above = Math.pow(10, n);// anything less than we don't have enough digits
while (num < above) {
num = nextVal(num);
}
return Number(`${num}`.charAt(n));
}
以上代码依靠数字检查,仅将其转换为字符串(也可以避免)