降低算法复杂度的方法
Methods of decreasing algorythm complexity
我正在尝试编写一个接受非负整数和 returns 非负整数对列表的函数,这些非负整数对的值 - 当平方时 - 总和为给定整数。
示例:
5 --> [ [1, 2] ]
25 --> [ [0, 5], [3, 4] ]
325 --> [ [1, 18], [6, 17], [10, 15] ]
我的解决方案在 IDE 中有效,但是当我将它提交给 codewars 时,我收到退出代码错误 139:致命错误:无效 table 大小分配失败 - JavaScript 堆溢出记忆。 codewars 文档表明这是由于算法效率低下造成的。
最初我的解决方案包含一个嵌套循环,它导致 运行 时间过长,但后来我重构了我的代码以删除它。尽管降低了复杂性,但我仍然遇到相同的错误。
有什么建议可以进一步降低复杂性吗?
const allSquaredPairs = (n) => {
//get array of all numbers between 0 and sqrt of n
let possibleNums = Array(n)
.fill()
.map((_, i) => {
if ((i + 1) ** 2 <= n) return i + 1; //only numbers lesser than sqrt of n
})
.filter(n => n!=undefined)
possibleNums = [0, ...possibleNums];
const matchingPairs = [];
while (possibleNums.length){
const num1 = possibleNums[0];
const num2 = possibleNums[possibleNums.length-1];
const sum = num1 ** 2 + num2 ** 2
if (sum === n) matchingPairs.push([num1, num2]);
if (sum > n ) possibleNums.pop()
else possibleNums.shift()
}
return matchingPairs;
};
console.log(allSquaredPairs(25));
您的解决方案分配一个长度为 n 的数组,然后对其进行迭代。这意味着您的解决方案的内存需求随着 n 的增加而线性增加。
您可以在不分配该数组的情况下实现这一点,这样无论 n 的值有多大,内存需求都是恒定的。
const examples = [
{ input: 5, output: [ [1, 2] ] },
{ input: 25, output: [ [0, 5], [3, 4] ] },
{ input: 325, output: [ [1, 18], [6, 17], [10, 15] ] },
{ input: Number.MAX_SAFE_INTEGER, output: [] }
];
function allSquaredPairs(n) {
const matchingPairs = [];
const smallestIntegerLargerThanSquareRootOfN = Math.ceil(Math.sqrt(n));
let lowerBound = 0;
let upperBound = smallestIntegerLargerThanSquareRootOfN;
while (lowerBound < upperBound) {
const sum = lowerBound ** 2 + upperBound ** 2;
if (sum === n) {
matchingPairs.push([lowerBound, upperBound]);
lowerBound += 1;
} else if (sum < n) lowerBound += 1;
else if (sum > n) upperBound -= 1;
else console.log("ERROR!")
}
return matchingPairs;
}
examples.forEach(({ input, output}) => console.log({ n: input, expected: JSON.stringify(output), " actual": JSON.stringify(allSquaredPairs(input)) }));
作为一个兴趣点,我在函数的开头用 let whatever = new Array(n)
尝试了这个,对于最大安全整数测试用例,它抛出了 RangeError: invalid array length
。这与您看到的错误不同,但它确实说明了分配长度为 n
的数组如何使事情复杂化。
我正在尝试编写一个接受非负整数和 returns 非负整数对列表的函数,这些非负整数对的值 - 当平方时 - 总和为给定整数。
示例:
5 --> [ [1, 2] ]
25 --> [ [0, 5], [3, 4] ]
325 --> [ [1, 18], [6, 17], [10, 15] ]
我的解决方案在 IDE 中有效,但是当我将它提交给 codewars 时,我收到退出代码错误 139:致命错误:无效 table 大小分配失败 - JavaScript 堆溢出记忆。 codewars 文档表明这是由于算法效率低下造成的。
最初我的解决方案包含一个嵌套循环,它导致 运行 时间过长,但后来我重构了我的代码以删除它。尽管降低了复杂性,但我仍然遇到相同的错误。
有什么建议可以进一步降低复杂性吗?
const allSquaredPairs = (n) => {
//get array of all numbers between 0 and sqrt of n
let possibleNums = Array(n)
.fill()
.map((_, i) => {
if ((i + 1) ** 2 <= n) return i + 1; //only numbers lesser than sqrt of n
})
.filter(n => n!=undefined)
possibleNums = [0, ...possibleNums];
const matchingPairs = [];
while (possibleNums.length){
const num1 = possibleNums[0];
const num2 = possibleNums[possibleNums.length-1];
const sum = num1 ** 2 + num2 ** 2
if (sum === n) matchingPairs.push([num1, num2]);
if (sum > n ) possibleNums.pop()
else possibleNums.shift()
}
return matchingPairs;
};
console.log(allSquaredPairs(25));
您的解决方案分配一个长度为 n 的数组,然后对其进行迭代。这意味着您的解决方案的内存需求随着 n 的增加而线性增加。
您可以在不分配该数组的情况下实现这一点,这样无论 n 的值有多大,内存需求都是恒定的。
const examples = [
{ input: 5, output: [ [1, 2] ] },
{ input: 25, output: [ [0, 5], [3, 4] ] },
{ input: 325, output: [ [1, 18], [6, 17], [10, 15] ] },
{ input: Number.MAX_SAFE_INTEGER, output: [] }
];
function allSquaredPairs(n) {
const matchingPairs = [];
const smallestIntegerLargerThanSquareRootOfN = Math.ceil(Math.sqrt(n));
let lowerBound = 0;
let upperBound = smallestIntegerLargerThanSquareRootOfN;
while (lowerBound < upperBound) {
const sum = lowerBound ** 2 + upperBound ** 2;
if (sum === n) {
matchingPairs.push([lowerBound, upperBound]);
lowerBound += 1;
} else if (sum < n) lowerBound += 1;
else if (sum > n) upperBound -= 1;
else console.log("ERROR!")
}
return matchingPairs;
}
examples.forEach(({ input, output}) => console.log({ n: input, expected: JSON.stringify(output), " actual": JSON.stringify(allSquaredPairs(input)) }));
作为一个兴趣点,我在函数的开头用 let whatever = new Array(n)
尝试了这个,对于最大安全整数测试用例,它抛出了 RangeError: invalid array length
。这与您看到的错误不同,但它确实说明了分配长度为 n
的数组如何使事情复杂化。