描述
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,返回两个数的乘积最小的,如果无法找出这样的数字,返回一个空数组即可。
返回值描述:
对应每个测试案例,输出两个数,小的先输出。
示例1
输入:
返回值:
解题思路
和41差不多,双指针一个指向开头一个指向末尾,向中间靠拢
但是这题隐藏了一个条件
对于乘积最小的两个数来说,两个数相差越大它们的乘积反而越小,故而第一个满足条件的数组就是结果
证明:
1 2 3 4 5
| a+b=s a=s-b a*b=b(s-b)=-(b-s/2)^2+s^2/4 所以当b趋近s/2即a趋近于b时乘积最大 反证得结论
|
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| function FindNumbersWithSum(array, sum) { let len = array.length; let left = 0; let right = len-1; let arr = []; while(left<right){ if(array[left]+array[right]>sum){ right--; }else if(array[left]+array[right]===sum){ let temp = []; temp.push(array[left]); temp.push(array[right]); arr.push(temp); right--; }else{ left++; } } if(arr.length===0){ return arr; } return arr[0] } module.exports = { FindNumbersWithSum : FindNumbersWithSum };
|
这题的隐藏条件可以省掉许多步骤,之前自己写的时候还专门存储了乘积再进行排序截取,还是需要多观察隐藏条件
弃用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| function FindNumbersWithSum(array, sum) { let len = array.length; let left = 0 let right = len - 1; let arr = []; while (left < right) { let total = array[left] + array[right]; if (total > sum) { right--; } else if (total == sum) { let temp = []; temp.push(array[left]); temp.push(array[right]) arr.push(temp); right--; } else if (total < sum) { left++; } } if (arr.length == 0) { return arr } for (let i = 0; i < arr.length; i++) { arr[i][2] = arr[i][0] * arr[i][1]; } let min = arr[0][2]; let ar = []; ar.push(arr[0]); for (let j = 0; j < arr.length; j++) { if (arr[j][2] < min) { ar.pop(); min = arr[j][2]; ar.push(arr[j]); } }
return ar[0].slice(0, 2) }
|