计算通过三个数组的最短路径

时间:2015-06-03 11:38:06

标签: javascript

我有三个数组,也可能是n。我们现在就拿三个。 他们有这样的价值观: -

Array1=[143, 181];
Array2=[41, 153, 241];
Array3=[22, 67, 131, 190];

我想找到这三个数组的元素,谁有最小的差异。 就像在这种情况下143,153,131有最小的差异。

2 个答案:

答案 0 :(得分:3)

假设您没有大量阵列,这里是一个解决方案,计算(和存储)所有路径:

// First let's use a sensible structure
var arrays = [Array1, Array2, Array3];

// Then, let's compute all possible paths
var paths = arrays[0].map(function(v){ return [v] });
for (var i = 1; i<arrays.length; i++) {
   var arr = arrays[i];
   for (var j=paths.length; j--; ) {
      var newPaths = arr.map(function(v){
        return paths[j].concat(v);
      })
      newPaths.unshift(j,1);
      [].splice.apply(paths, newPaths);
   }
}

// Now, let's just take the shortest one
var shortestDistance = Infinity,
    shortestPath = null;
paths.forEach(function(path){
  var distance = 0;
  for (var i=1; i<path.length; i++) {
    distance += Math.abs(path[i]-path[i-1]);
  }
  if (distance<shortestDistance) {
    shortestDistance = distance;
    shortestPath = path;
  }
});

// Finally, let's log the result
console.log(shortestDistance, shortestPath);

记录

32
[143, 153, 131]

答案 1 :(得分:0)

也许我理解你想要的东西。

您必须探索一个树,其中每个数组都是每个节点的所有后代的列表,如下所示:

          * (root)
       /      \
   143          181
  / | \        / | \
41 153 241   41 153 241
/|\/|\ /|\   /|\/|\ /|\
........ descendants from 3rd array

然后,您可以将叶子权重计算为该叶子的祖先节点路径的差异。

然后你想找到所有叶节点的最小权重。

如果以递归方式实现它并保留变量minSoFar和节点副本以保持在树中任何叶子上找到的最小值,那就太难了。

一旦这个抽象的数据结构在概念上清晰,那么实现就很简单直接。

编辑:此实现具有小内存占用(仅调用堆栈),并且应该以与非递归版本相同的复杂度执行。在这个页面上显示的递归和非递归实现中,复杂性由抽象数据结构决定。由于内存占用量小,应该可以计算相当深的结构(许多数组),尽管计算时间呈指数增长。

function recursiveMinDiff(arrays)
{
  var minSoFar, minNodes;

  function computeMinDiff(values)
  {
    var i, vs, total;

    vs = values.slice();
    vs.sort(function (a,b) {      // ascending order
      return a - b;
    });

    total = 0;
    for (i = 0; i < vs.length - 1; i++)
    {
      total += vs[i + 1] - vs[i]; // always non-negative
    }

    return total;
  }

  function mindiff(arrays, stack)
  {
    var i, diff, level;

    level = stack.length;
    if (level === arrays.length)  // this is a leaf
    {
      diff = computeMinDiff(stack);
      if (diff < minSoFar)
      {
        minSoFar = diff;          // side-effect on min*
        minNodes = stack.slice(); // clone array
      }
      return;
    }

    for (i = 0; i < arrays[level].length; i++)
    {
      stack.push(arrays[level][i]);
      mindiff(arrays, stack);
      stack.pop();
    }
  }

  minSoFar = Number.MAX_VALUE;
  minNodes = [];
  mindiff(arrays, []);

  return minNodes;
}