我对编码相当陌生,并被列入每日编码问题邮件列表并得到了这个问题:
给定一个数字列表和一个数字 k,返回列表中的任意两个数字加起来是否为 k。
我的解决方案(经过一些 stackoverflow 挖掘后)看起来像这样;
function problemOne_Solve()
{
const k = 17;
const values = [11, 15, 3, 8, 2];
for (i=0; i < values.length; i++) {
if ( values.find( (sum) => { return k-values[i] === sum} ) ) return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
我想知道为什么它有效。在我看来,带有 fat-arrow 函数的部分关闭了 if 语句条件逻辑内的括号。在 if 语句之后没有这样的括号,我认为这是必需的。
我还想知道如何输出总和为“k”的一对或多对,以进一步构建解决方案。例如,我希望能够在页面上显示对。
.find接受一个回调,为数组中的每个项目调用该回调(或者直到找到匹配项为止)。回调的第一个参数是正在迭代的项目。如果找到匹配项(如果回调的返回值对于任何元素都是真实的),则返回.find导致真实返回值的项目。
因此,在第一次迭代中,i = 0and values[i]is会首先检查是否,然后检查是否,然后检查是否,等等。11(sum) => { return k-values[i] === sum}17 - 11 === 1117 - 11 === 1517 - 11 = 3
如果数组中的两个数字相加等于 ,则通常会满足此条件k,但该算法有错误。例如,由以下组成的数组[1]将在第一次迭代时将 1 与自身进行比较,总计为 2:
function problemOne_Solve() {
const k = 2;
const values = [1];
for (i=0; i < values.length; i++) {
if ( values.find( (sum) => { return k-values[i] === sum} ) ) return true;
}
return false;
}
console.log(problemOne_Solve());Run Code Online (Sandbox Code Playgroud)
那是错的。另一个问题是.find返回找到的值。但是,如果数组是数字数组,则找到的值可能为 0,而 0 为 false。因此下面的示例应该返回,true因为两个元素之和为 0(0 和 0),但它返回false:
function problemOne_Solve() {
const k = 0;
const values = [0, 0];
for (i=0; i < values.length; i++) {
if ( values.find( (sum) => { return k-values[i] === sum} ) ) return true;
}
return false;
}
console.log(problemOne_Solve());Run Code Online (Sandbox Code Playgroud)
为了得到正确的结果并O(n ^ 2)降低从到 的计算复杂度O(n),请对数组进行一次迭代。创建一个对象,其键是要迭代的数字,并在每次迭代时检查target - currNum该对象上是否存在键(其中target是目标总和,currNum是数组中的当前数字):
function problemOne_Solve() {
const target = 17;
const values = [11, 15, 3, 8, 2];
const obj = {};
for (const currNum of values) {
if (obj.hasOwnProperty(target - currNum)) {
return true;
}
obj[currNum] = true;
}
return false;
}
console.log(problemOne_Solve());Run Code Online (Sandbox Code Playgroud)
我还想知道如何输出总和为“k”的一对或多对,以进一步构建解决方案。例如,我希望能够在页面上显示这些对。
找到匹配项时不要立即返回,而是推送到数组,然后在函数末尾返回该数组。另外,不要将对象值设置为true(或false),而是将它们设置为迄今为止找到的数字出现的次数(并在找到匹配时减少匹配数字):
function problemOne_Solve() {
const target = 17;
const values = [11, 15, 3, 8, 2, 17, 0, 0, 17];
const obj = {};
const matches = [];
for (const currNum of values) {
const otherNum = target - currNum;
if (obj[otherNum]) {
obj[otherNum]--;
matches.push([currNum, otherNum]);
}
obj[currNum] = (obj[currNum] || 0) + 1;
}
return matches;
}
console.log(problemOne_Solve());Run Code Online (Sandbox Code Playgroud)
而且 if 语句后面没有这样的括号,我认为这是必需的。
if当(orelse if或)之后有单个语句时不需要括号else,例如:
if (true) console.log('true');
else console.log('this will not log');Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
103 次 |
| 最近记录: |