嵌套列表权重和javascript

时间:2018-09-02 23:30:34

标签: javascript arrays algorithm array-algorithms

我正在尝试解决这个问题,我们针对给定的数字数组计算嵌套权重总和。

  

给出一个嵌套的整数列表,返回整数中的所有整数之和   列表按其深度加权。

例如:

  

[[[1,1],2,[1,1]] ====>解决方案是10。

     

深度2为4,深度1为2。

这是我写的代码:

var depthSum = function (nestedList, sum=0, depth=1) {
    for(let i=0; i<nestedList.length; i++){
        let val = nestedList[i];
        if (Array.isArray(val)) {
            return depthSum(val, sum, depth+1);
        } else {
            sum += val * depth;
        }
    };
    return sum;
};

我正在尝试解决相反的问题。即

  

给出一个嵌套的整数列表,返回整数中的所有整数之和   列表按其深度加权。体重从根部增加到哪里   叶子,现在权重是从下向上定义的。即叶子水平   整数的权重为1,而根级整数的权重最大   重量。

示例: [[1,1],2,[1,1]] ===>解决方案是8。

如何使用相同的方法来解决此问题?

https://leetcode.com/problems/nested-list-weight-sum-ii/description/

4 个答案:

答案 0 :(得分:2)

应该可以完成这项工作,但是我希望我有一个高级leetcode帐户来验证这一点。想法是进行搜索以找到结构中的最大深度,然后使用您以前的算法,但将深度计算取反。同样,不进行递归也意味着超时的机会更少,也没有炸毁堆栈的机会。我添加了一些基本测试用例,但同样,没有保证。

const search = a => {
  let sum = 0;
  let depth = 0;
  const stack = [[a, 0]];

  while (stack.length) {
    const curr = stack.pop();

    if (curr[1] > depth) {
      depth = curr[1];
    }

    for (const e of curr[0]) {
      if (Array.isArray(e)) {
        stack.push([e, curr[1] + 1]);
      }
    }
  }

  stack.push([a, ++depth]);

  while (stack.length) {
    const curr = stack.pop();

    for (const e of curr[0]) {
      if (Array.isArray(e)) {
        stack.push([e, curr[1] - 1]);
      }
      else {
        sum += e * curr[1];
      }
    }
  }

  return sum;
};

console.log(search([[1,1],2,[1,1]]));
console.log(search([]));
console.log(search([6]));
console.log(search([[[[3]]]]));
console.log(search([[2],1]));

答案 1 :(得分:2)

像原始的depthSum这样的基本递归解决方案可能无法满足第二个要求,因为您需要先确定总深度,然后才能知道数组顶层项的乘数。一种选择是先找出最深数组的深度,然后使用与原始depthSum类似的方法。

您可以使用reduce(这是将对象转换为单个值的适当方法)和条件(三元)运算符,以使您的代码简洁明了,减少重复:

const depthCheck = (item) => (
  Array.isArray(item)
  ? 1 + Math.max(...item.map(depthCheck))
  : 0
);

// verification:
console.log(depthCheck([[1,1],2,[1,1]])); // total depth 2
console.log(depthCheck([[1,1],2,[1,1,[2,2]]])) // total depth 3
console.log(depthCheck([[1,1,[2,[3,3]]],2,[1,1,[2,2]]])) // total depth 4
console.log('-----')

const depthSum = (nestedList, weight=depthCheck(nestedList)) => (
  nestedList.reduce((a, val) => a + (
    Array.isArray(val)
    ? depthSum(val, weight - 1)
    : val * weight
  ), 0)
);

console.log(depthSum([[1,1],2,[1,1]])) // (2)*2 + (1+1+1+1)*1
console.log(depthSum([[1,1],2,[1,1,[2,2]]])) // (2)*3 + (1+1+1+1)*2 + (2+2)*1
console.log(depthSum([[1,1,[2,[3,3]]],2,[1,1,[2,2]]])) // (2)*4 + (1+1+1+1)*3 + (2)*2 + (3+3)*1

答案 2 :(得分:1)

如果在遍历过程中将每个深度的元素之和存储在数组中,则无需两次遍历嵌套数组即可执行此操作。然后,您知道该数组的长度是最大深度,您可以将总和乘以正确的权重。

可以使用递归或堆栈进行遍历,如其他答案所述。这是使用递归的示例:

function weightedSum(array) {
    var sums = [], total = 0;
    traverse(array, 0);
    for (var i in sums)
        total += sums[i] * (sums.length - i);
    return total;

    function traverse(array, depth) {
        if (sums[depth] === undefined)
            sums[depth] = 0;
        for (var i in array) {
            if (typeof array[i] === "number")
                sums[depth] += array[i];
            else traverse(array[i], depth + 1);
        }
    }
}

console.log(weightedSum([[],[]]));
console.log(weightedSum([[1,1],2,[1,1]]));
console.log(weightedSum([1,[[],2,2],1,[[3,3,[[5]]],[3]],[]]));

答案 3 :(得分:-1)

也许可以使用一个简单的递归化简器进行以下操作。

var weightOfNested = (a,d=1) => a.reduce((w,e) => Array.isArray(e) ? w + weightOfNested(e,d+1)
                                                                   : w + d*e, 0);
console.log(weightOfNested([[1,1,[3]],2,[1,1]]));

好吧,正如注释中提到的,上面的代码更权衡了更深层的元素。为了称重浅层,我们需要提前知道阵列的深度。我相信这种方式最终会使您遍历数组两次……一次用于深​​度,一次用于计算加权和。

var weightOfNested = (a, d = getDepth(a)) => a.reduce((w,e) => Array.isArray(e) ? w + weightOfNested(e,d-1)
                                                                                : w + d*e, 0),
    getDepth       = (a, d = 1, t = 1) => a.reduce((r,e) => Array.isArray(e) ? r === t ? getDepth(e,++r,t+1)
                                                                                       : getDepth(e,r,t+1)
                                                                             : r, d);
console.log(weightOfNested([[1,1,[3]],2,[1,1]])); // depth is 3