Это можно сделать за один l oop с умным использованием объекта и знанием того, что индексы можно использовать только один раз.
function pairwise(arr, arg) {
let map = {};
let output = 0;
let length = arr.length;
for (let i = 0; i < length; i++) {
let subArr = map[arr[i]];
if(subArr && subArr[0] !== undefined) {
//there is an index waiting to pair, remove it and add to output
output += subArr.pop() + i;
} else {
//add this index to its pair slot
let left = arg - arr[i];
if(!map[left]) map[left] = [];
map[left].unshift(i);
}
}
return output;
}
console.log(pairwise([0, 0, 0, 0, 1, 1], 1), "should be 10");
console.log(pairwise([1, 4, 2, 3, 0, 5], 7), "should be 11");
console.log(pairwise([], 100), "should be 0");
console.log(pairwise([1, 3, 2, 4], 4), "should be 1");
Ключи карты представляют другое значение, необходимое для создания пары , а значения карты представляют собой массивы индексов, которые имеют значение что сделало бы пару. Индексы вставляются с использованием unshift()
, так что pop()
возвращает первый, который был вставлен - самый маленький.
Итерация с начала гарантирует, что самые маленькие пары будут найдены первыми, а карта гарантирует, что любые более поздний индекс будет точно знать, какой самый ранний индекс, который мог бы образовать пару.