如何解决使用多个指针作为解决方案的averagePair问题
我正在尝试解决以下问题:
到目前为止,我想出了什么:
function averagePair(arr,tar){
if (arr.length < 2){
return false
}
let x = 0
for (var y = 1; y < arr.length; y++){
if ((arr[x] + arr[y]) / 2 == tar){
return true
}
else {
x++;
}
}
return false
}
我知道此解决方案不正确,有人可以解释原因吗?它适用于某些情况,但并非全部
解决方法
您仅比较了相邻元素,例如[0]
与[1]
,以及[1]
与[2]
。您还需要比较[0]
与[2]
,依此类推。最简单的调整是使用嵌套循环:
for (let x = 0; x < arr.length; x++) {
for (let y = 0; y < arr.length; y++) {
if (x !== y) {
// test arr[x] against arr[y]
但是使用Set来跟踪到目前为止所发现的内容会更优雅,并且计算复杂度更低(O(n)
而不是O(n ^ 2)
)
const nums = new Set();
for (const num of arr) {
if (nums.has(tar - num)) {
return true;
} else {
nums.add(num);
}
}
function averagePair(arr,tar){
const nums = new Set();
for (const num of arr) {
if (nums.has(tar - num)) {
return true;
} else {
nums.add(num);
}
}
return false;
}
console.log(averagePair([-2,3,2],0));
console.log(averagePair([-2,3],0));
,
存在一种解决方案,该解决方案具有O(1)
个额外的空间复杂度和O(n)
个时间复杂度。
由于对数组进行了排序,因此具有两个索引是有意义的:一个索引从数组的开始到结束(例如y
),另一个从数组的结束到开始(例如x
)。 / p>
这是代码:
function averagePair(arr,tar){
// That's now included in for-loop condition
// if (arr.length < 2) {
// return false;
// }
let x = arr.length - 1;
for (var y = 0; y < x; y++) {
// Division may lose precision,so it's better to compare
// arr[x] + arr[y] > 2*tar
// than
// (arr[x] + arr[y]) / 2 > tar
while (y < x && arr[x] + arr[y] > 2*tar) {
x--;
}
if (x != y && arr[x] + arr[y] == 2*tar) {
return true;
}
}
return false;
}
这是一种两指针技术:对于当前循环迭代,我们将减小x
直到a[x] + a[y] > 2*tar
,因为我们需要找到最接近的匹配项。在下一个for循环迭代中,a[y]
大于或等于前一个迭代,因此检查a[z] + a[y] == 2*tar
是否有任何z > x
是没有意义的。我们将一直这样做直到索引不相等,这意味着没有匹配项。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。