【问题标题】:Two sum problem with duplicates - more idiomatic Javascript solution重复的两个和问题 - 更惯用的 Javascript 解决方案
【发布时间】:2020-02-09 17:31:01
【问题描述】:

给定一个包含重复的整数数组,返回一个所有索引对总和为零的数组。

[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 相比):

  1. 将一个可枚举对象简化为另一个可枚举对象(each_with_object)。
  2. 初始化一个映射,使每个新键对应一个对象(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;
  }, []);
}

【问题讨论】:

  • 我认为更惯用的 Ruby 解决方案是[*0...arr.size].combination(2).select { |i,j| arr[i] == -arr[j] }

标签: javascript ruby


【解决方案1】:
function two_sum(arr) {
    let hash = new Map();

    return arr.reduce((results, ele, i) => {
        if (hash.has(-ele)) {
            results = results.concat(hash.get(-ele).map(e => [i, e]))
        }

        hash.set(ele, hash.get(ele) || []);
        hash.get(ele).push(i);

        return results;

    }, []);
}

【讨论】:

  • 请在您的回答中描述问题是什么,以及这个 sn-p 将如何解决它,以帮助其他人理解这个答案
【解决方案2】:

可能是这样的:

const sumZeroIndexPairs = arr => {
  const hashMap = arr.reduce(
    (result, value, index, list) => {
      list.forEach((n, i) => {
        const key = [ index, i ].sort().join('_')
        const sum = value + n
        result[key] = sum
      })
      return result
    },
    {}
  );
  
  return Object.entries(hashMap)
    .filter( ([key, value]) => value === 0 )
    .map(([key]) => key.split('_'));
}

console.log(sumZeroIndexPairs([1, 2, 3, -1, 5, -5, 7, 9, -7, 2, -2]))

【讨论】:

  • 在回答时,重要的是要解释为什么这是问题的适当解决方案。我们的目标不仅是回答眼前的问题,还要进行教育,让他们知道下次如何解决问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多