我已经使用两个循环在javascript中实现了解决方案,下面是代码
function getNums(arr){
var res = [];
var found = {};
var i, j;
var arrLen = arr.length;
for(i=0; i<arrLen; i++){
if(!found.hasOwnProperty(arr[i])){
for(j=0; j<arrLen; j++){
if(arr[i]+arr[j] === 0){
var num = arr[i];
if(num > 0){
res.push(num);
found[num] = 1;
}
}
}
}
}
return res;
}
console.log(getNums[-1, -2, 0, -4, 1, 4, 6]); // Output: [1, 4]
其时间复杂度为O(n2)。有人可以建议更好的解决方案/上面进行改进以降低复杂性吗?
答案 0 :(得分:4)
您只需将数组添加到Set中,然后过滤以包含在Set中。确定某物是否在集合中是恒定时间:
let arr = [-1, 2, 3, 1 , 3, -3, 4, -6]
let s = new Set(arr)
// all positive numbers with corresponding negatives in the set
let filtered = arr.filter(item => item > 0 && s.has(-1 * item))
console.log(filtered)
另一种方法是对数组进行排序,然后在进行匹配时沿数组向上移动两个指针。结果将被排序,但是可能与原始数组的顺序不同:
let arr = [-2, -3, 2, 5, 3, 1, -6, 2, -5]
arr.sort()
// get startig indexes
let i = 0, j = arr.findIndex(n => n > 0)
let res = []
if (j > -1) { // only if there are positive numbers in the array
while(arr[i] < 0 && j < arr.length){
if (-1 * arr[i] === arr[j]){
res.push(arr[j++])
} else if(-1 * arr[i] > arr[j]){
j++
} else if(-1 * arr[i] < arr[j]){
i++
}
}
}
console.log(res)
答案 1 :(得分:1)
您可以通过计数值来采用单循环方法。
function getNums(array) {
var count = Object.create(null),
result = [];
array.forEach(v => {
if (count[-v]) {
result.push(Math.abs(v));
count[-v]--;
return;
}
count[v] = (count[v] || 0) + 1;
});
return result;
}
console.log(getNums([1, 2, -3, -4, 2, 3, 4, 4, -4]));
答案 2 :(得分:0)
另一种解决方案是使用过滤器,并包括经过优化的原型功能。
const getNums = (arr) => arr.filter((num, index) => num > 0 && !arr.includes(num, index + 1) && arr.includes(-num));
答案 3 :(得分:0)
在投票失败之前...这个答案不是最短的javascript代码,而是算法-我认为这是原始问题所在。
摆脱嵌套循环的一种方法是使用更多的内存来存储中间结构。在您的情况下,您不仅要存储“ found”标志,还要存储正,负值,以便在每次迭代时都可以设置Found标志。然后,您还可以使用“找到”标志来防止第二次添加结果。
var f = function(arr) {
let hash = {};
let res = [];
for (var i = 0; i < arr.length; i++) {
// put value into the hash map for future use
hash[arr[i]] = arr[i];
var absVal = Math.abs(arr[i]);
// if value is not 0 AND if it has not been found yet (x+value hash) AND if both negative and positive values are present
if( arr[i] !== 0 && !hash["x"+absVal] && (hash[arr[i]] + hash[-arr[i]] === 0)){
// then set the found hash to true
hash["x"+absVal] = true;
// and push to the resut
res.push(absVal);
}
}
// return the result
return res;
}