【问题标题】:How to find the 4 number sum given an array with no duplicate values and a target sum?给定一个没有重复值和目标总和的数组,如何找到 4 数字总和?
【发布时间】:2020-02-27 10:05:18
【问题描述】:

我试图找到给定数组的四个数字总和。任务是在数组中找到总和为目标和的所有四联体,并以无特定顺序返回所有这些四联体的二维数组。如果没有四个唯一数字的总和达到目标总和,则该函数应返回一个空数组。

我尝试了以下代码似乎工作正常,但由于重复元素,我得到了一个额外的四倍。

  function fourSum([1,2,3,4,5,6,7],10) {
    var hash = {};
    var quadruples = [];
    for(var i=0; i<array.length; i++){
        for(var j=0; j<array.length;j++){
            var Q = 0;
            var P = 0;
            if(i<j){
                Q = array[i]+array[j];

          if(hash[(targetSum - Q)]){
                    for(var k=0; k< hash[(targetSum - Q)].length; k++){
                        var combination = [hash[(targetSum - Q)][k][0] , hash[(targetSum - Q)][k][1] ,array[i], array[j]];
                        quadruples.push(combination);
                    }
                }
            }
            if(i>j){
                P = array[i]+array[j];
                if(hash[P]){
                    hash[P].push([array[i], array[j]]);
                }else{
                    hash[P] = [[array[i], array[j]]];
                }
            }
        }
    }

    return quadruples;
  }

这会返回以下内容:{[2, 1, 2, 5], [2, 1, 3, 4]} 这是不正确的,因为在 [2, 1, 2, 5] 中,我们有 2 两次。我无法找出我的代码哪里错了。

【问题讨论】:

    标签: javascript arrays algorithm


    【解决方案1】:

    我建议使用递归方法,只访问所有索引一次,但要么存储元素,要么不存储,然后再次调用函数。

    这种方法有两部分,用于准备结果集的函数和对递归函数iter的初始调用。 Tha 调用从索引零开始,一个用于收集项目的空临时数组和零作为 temp 数组的累加总和。

    函数iter有两部分,

    1. 退出条件,比如

      • 检查temp 是否具有所需长度,然后检查total 和所需总和并将temp 作为部分结果。退出函数/递归。

      • 检查total 是否大于sum(如果所有数字都是正数,这是短路)或者如果index 不是值,则退出函数/递归。

    2. 再次拨打iter

      • 使用新值,例如将项目和值添加到total
      • 没有新值,只增加索引。

    function subSetSum(array, sum, length) {
        function iter(index, temp, total) {
            if (temp.length === length) {
                if (total === sum) result.push(temp);
                return;
            }
            if (total > sum || index >= array.length) return;
            iter(index + 1, [...temp, array[index]], total + array[index]);
            iter(index + 1, temp, total);
        }
    
        var result = []
        iter(0, [], 0);
        return result;
    }
    
    console.log(subSetSum([1, 2, 3, 4, 5, 6, 7], 10, 4)); // only a single array
    console.log(subSetSum([1, 2, 3, 4, 5, 6, 7], 15, 4));
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案2】:

      我们可以将这个任务分为 2 个动作:

      • 我们可以找到给定数组的所有组合
      • 找到满足条件的第一个组合

      所以第一个动作可以使用递归方法完成。此代码基于this great answer

      let allCombinations = [];
      const getAllCombinations = (set, k, partial) => {
          if (!partial) partial = [];
          for (var element in set) {
              if (k > 1) {
                  var set_copy = set.slice();
                  set_copy.splice(element, 1);
                  getAllCombinations(set_copy, k - 1, partial.concat([set[element]]));
              }
              else {
                  allCombinations.push(partial.concat([set[element]]));
              }
          }
      }
      

      第二个动作是找到满足所需条件的数组:

      const findCombination = (arr, desiredSum) => {
          const sum = arr.reduce((a, c) => {
              a+=c;
              return a;
          }, 0);
      
          if (sum == desiredSum)
              return arr;
      
          return false;
      }
      

      一个例子:

      const getSubsetSum = (arr, sum, length) => {
      
          let allCombinations = [];
          const getAllCombinations = (set, k, partial) => {
              if (!partial) partial = [];
              for (var element in set) {
                  if (k > 1) {
                      var set_copy = set.slice();
                      set_copy.splice(element, 1);
                      getAllCombinations(set_copy, k - 1, partial.concat([set[element]]));
                  }
                  else {
                      allCombinations.push(partial.concat([set[element]]));
                  }
              }
          }
      
          getAllCombinations(arr, length);
      
          const findCombination = (arr, desiredSum) => {
              const sum = arr.reduce((a, c) => {
                  a+=c;
                  return a;
              }, 0);
      
              if (sum == desiredSum)
                  return arr;
      
              return false;
          }
      
          return allCombinations.find(s => findCombination(s, sum));
      }
      console.log(getSubsetSum([1, 2, 3, 4, 5, 6, 7], 10, 4));
      console.log(getSubsetSum([1, 2, 3, 4, 5, 6, 7], 15, 4));

      【讨论】:

        猜你喜欢
        • 2020-08-30
        • 2019-04-26
        • 1970-01-01
        • 1970-01-01
        • 2010-11-16
        • 1970-01-01
        • 1970-01-01
        • 2013-11-03
        相关资源
        最近更新 更多