https://www.freecodecamp.cn/challenges/pairwise
找到你的另一半
都说优秀的程序员擅长面向对象编程,但却经常找不到另一半,这是为什么呢?因为你总是把自己局限成为一个程序员,没有打开自己的思维。
这是一个社群的时代啊,在这里你应该找到与你有相同价值观但又互补的另一半。
譬如:你编程能力强,估值11分,如果以20分为最佳情侣来计算,你应该找一个设计能力强,估值为9分的女生。
那么当你遇到一个设计能力为9分的女生,千万别犹豫,大胆去表白。千万别以为后面的瓜比前面的甜哦。
举个例子:有一个能力数组[7,9,11,13,15]
,按照最佳组合值为20来计算,只有7+13和9+11两种组合。而7在数组的索引为0,13在数组的索引为3,9在数组的索引为1,11在数组的索引为2。
所以我们说函数:pairwise([7,9,11,13,15],20)
的返回值应该是0+3+1+2的和,即6。
我们可以通过表格来更直观地查看数组中索引和值的关系:
Index | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
Value | 7 | 9 | 11 | 13 | 15 |
任务:帮右边的pairwise函数实现上面的功能。
当你遇到困难的时候,记得开大招’Read-Search-Ask’。
这是一些对你有帮助的资源:
pairwise([1, 4, 2, 3, 0, 5], 7) 应该返回 11.
pairwise([1, 3, 2, 4], 4) 应该返回 1.
pairwise([1, 1, 1], 2) 应该返回 1.
pairwise([0, 0, 0, 0, 1, 1], 1) 应该返回 10.
pairwise([], 100) 应该返回 0.
思路
这题,看题面的意思,就是在数组中找两个和为传入参数 arg 的项,把它们的索引值相加并返回。但事实上,我们还得考虑几种特殊情况。
例如,测试数据的第三项:
pairwise([1, 1, 1], 2) 应该返回 1.
也就是说,对于单项相同大小的数组项,只考虑由前至后遍历时遇到的第一组解。
测试数据的第五项:
pairwise([], 100) 应该返回 0.
这个好解决,只要在函数前部加一个判断就可以啦。如果传入空数组,则返回0.
if(arr.length === 0){
return 0;
}
回到题目的主要逻辑,要解决这个问题,其实就是两个arr在自己和自己比较。看看这一项加另一项是否等于期望值。为了让两个arr自我遍历,我用了两个 for() 循环进行嵌套。
for(var i = 0; i < arr.length; i++){
for(var j = 0; j < arr.length; j++){
//do something...
}
}
内层 for() 循环的内部,就是我们的主战场了。当 i 和 j 相等时,它们指向的是同一项,这种情况是要排除的。同时,加上题目的要求,寻找两项和为 arg 的项。
if(i !== j && arr[i] + arr[j] === arg){
//do something...
}
我们需要在循环外部声明一个空数组来接收符合条件的索引值,恩,假设我们已经有了一个名为 temp 的空数组。
temp.push(i,j);
为了不使序号已经在结果集中的对应项重复被遍历,我们可以使用 delete 删除对应下标的项。这种方式数组长度不变,被删除的项在数组中再次访问就变为undefined了,原来数组的索引也保持不变。
delete arr[i];
delete arr[j];
这样等同于:
arr[i] = undefined;
arr[j] = undefined;
最后,把得到的结果集用 reduce()
进行归并,完美!
解法
function pairwise(arr, arg) {
var temp = [];
if(arr.length === 0){
return 0;
}
for(var i = 0; i < arr.length; i++){
for(var j = 0; j < arr.length; j++){
if(i !== j && arr[i] + arr[j] === arg){
temp.push(i,j);
delete arr[i];
delete arr[j];
break;
}
}
}
return temp.reduce(function(prev,cur){
return prev + cur;
});
}
pairwise([1,4,2,3,0,5], 7);