Javascript 递归函数的执行超时
我正在对CodeWars进行Kata,这对大多数阵列都很有效,但当算法处理非常大的阵列时,我会陷入困境: 给定一个正整数数组X,其元素将根据需要多次运行以下操作进行转换:Javascript 递归函数的执行超时,javascript,algorithm,Javascript,Algorithm,我正在对CodeWars进行Kata,这对大多数阵列都很有效,但当算法处理非常大的阵列时,我会陷入困境: 给定一个正整数数组X,其元素将根据需要多次运行以下操作进行转换: if X[i] > X[j] then X[i] = X[i] - X[j] 当无法进行更多转换时,返回其和(“最小可能和”) 例如,inputX=[6,9,21]元素的连续转换如下: X_1 = [6, 9, 12] # -> X_1[2] = X[2] - X[1] = 21 - 9 X_2 = [6, 9,
if X[i] > X[j] then X[i] = X[i] - X[j]
当无法进行更多转换时,返回其和(“最小可能和”)
例如,inputX=[6,9,21]
元素的连续转换如下:
X_1 = [6, 9, 12] # -> X_1[2] = X[2] - X[1] = 21 - 9
X_2 = [6, 9, 6] # -> X_2[2] = X_1[2] - X_1[0] = 12 - 6
X_3 = [6, 3, 6] # -> X_3[1] = X_2[1] - X_2[0] = 9 - 6
X_4 = [6, 3, 3] # -> X_4[2] = X_3[2] - X_3[1] = 6 - 3
X_5 = [3, 3, 3] # -> X_5[1] = X_4[0] - X_4[1] = 6 - 3
返回的输出是最终转换的总和(这里是9)
这是我的递归解决方案:
const solution =(numbers) => {
//1. find bigger and smallest number in the array, and keep the index of the biggest number
let bigger = Math.max(...numbers)
let smaller = Math.min(...numbers)
let index = numbers.findIndex((n)=> n === bigger)
//2. return the result if the result of the subtraction is positive or null
if (smaller === bigger) {
return numbers.reduce((a,c) => a + c)
}
//3.substract and replace
numbers.splice(index, 1, bigger-smaller)
return solution(numbers)
}
所以我想知道我的解决方案中的哪个操作导致了超时;处理器进行循环最耗时的是什么?解决方案的好处在于,它认识到当所有值都相同(
较小===较大
)时,应计算并返回总和
但是,从最大值中减去最小值来替换最大值并不好。你有兴趣使这些值尽可能小,所以这是你可能做出的最糟糕的选择。使用其他任何一对进行减法已经是一种改进
此外:
- 每次递归调用都必须扫描整个数组,这非常耗时。它使您的解决方案成为O(以下是正确的解决方法!更短、更高效
const gcd = (a, b) => b ? gcd(b, a % b) : a; const solution = numbers => numbers.length * numbers.reduce(gcd);
你是对的,正确的方法不是使用欧几里德算法,而是用这种方法找出gcd。谢谢!!那么?你的问题是什么?“哪个操作最耗时”问调试器?你要找的工具是一个分析器,另请参见解决Kata,实际答案可能是“所有这些”这至少可以用O(n logn)来解决,甚至可以用O(n)来代替O(n²)问问自己:如果你有,例如,20和3,那么“尽可能多地从20中减去3”是什么意思?结果会是什么?通过什么数学运算,你可以一次性获得相同的结果?要优化,我会首先对数组进行排序,当nVER值改变时,它会按排序顺序排列。很明显,这是一个索引游戏。每次搜索最大和最小值都不是最佳算法。我认为术语公分母会导致.Try:-)谢谢你的回答,今晚我来试试!!