给定一个包含重复的整数数组,返回一个数组,其中所有索引对的总和为零。
[1, 2, 3, -1, 5, -5, 7, 9, -7, 2, -2] -> [ [ 3, 0 ], [ 5, 4 ], [ 8, 6 ], [ 10, 1 ], [ 10, 9 ] ]
我的JS解决方案:
function pairs(values, i) {
if (values) {
values.push(i);
return values;
}
return [i];
}
function twoSum(arr) {
const results = [];
const map = new Map();
arr.forEach((ele, i) => {
if (map.get(-ele)) {
map.get(-ele).forEach((e) => results.push([i, e]));
}
map.set(ele, pairs(map.get(ele), i));
});
return results;
}
来自 Ruby,这是我的 Ruby 解决方案:
def two_sum(arr)
hash = Hash.new { |h, k| h[k] = [] }
arr.each.with_index.each_with_object([]) do |(ele, i), results|
if hash.key?(-ele)
hash[-ele].each { |e| results << [i, e] }
end
hash[ele] << i
end
end
这个想法是每个 hashmap 键都有一个数组,对于数组中的每个元素,我们检查 hashmap 是否有 -element 键,如果有,则将当前索引和每个值的对推送到结果数组中。
我怎样才能使 JS 解决方案更惯用?我在 JS 默认库中找不到以下内容(与 Ruby 相比):
将一个可枚举对象缩减为另一个可枚举对象(each_with_object)。
初始化一个映射,使每个新键对应一个对象(Hash.new([])、Hash.new(0) 等)。
对选择的解决方案进行了一点重构,最终得到了这样的结果:
function twoSum(arr) {
const hash = new Map();
return arr.reduce((results, ele, i) => {
if (hash.has(-ele)) hash.get(-ele).forEach((e) => results.push([i, e]));
hash.get(ele) ? hash.get(ele).push(i) : hash.set(ele, [i]);
return results;
}, []);
}
喵喵时光机
慕娘9325324
相关分类