如何从多个数组中挑选数组,使所有元素都以线性方式上升

How to pick arrays from many arrays so that all elements are rising in a linear way

我有一张包含这些阵列的地图。我想要的是从 0-10 中选择最少的项目。例如。

 {
      '11100171' => [ 0, 1, 2, 3 ],
      '11100060' => [ 1, 2, 3 ],
      '12100062' => [ 4 ],
      '12100012' => [ 5, 6, 7 ],
      '12100011' => [ 6, 7 ],
      '12100020' => [ 7 ],
      '12100121' => [ 7 ],
      '11100130' => [ 8, 9 ],
      '11100140' => [ 8, 9 ],
      '11100470' => [ 8, 9 ],
      '11400080' => [ 8, 9, 10 ]
    }

我会选择

从这里开始。

这是一个图形寻路问题。如果我们假设所有数组都由连续的数字组成,我们可以将一个这样的数组解释为图中的一条边,该边将第一个数字标识的节点与最后一个数字加 1 标识的节点连接起来。

然后目标就是找到从起点到终点+1的最短路径。

为此,我们可以在该图中使用 breadth-first 搜索。

下面是 JavaScript 这个想法的实现:

function createAdjacencyList(data) {
    let adj = {};
    for (let key in data) {
        let arr = data[key];
        let start = arr[0];
        if (!adj[start]) adj[start] = [];
        adj[start].push(arr);
    }
    return adj;
}

function shortestPath(adj, start, end) { // BFS algo
    let frontier = [start];
    let comeFrom = {};
    while (frontier.length) {
        let nextFrontier = [];
        for (let node of frontier) {
            if (node === end + 1) { // Unwind path
                let path = [];
                do {
                    arr = comeFrom[node];
                    path.push(arr);
                    node = arr[0];
                } while (node != start);
                return path.reverse();
            }
            if (adj[node]) {
                for (let arr of adj[node]) {
                    let neighbor = arr.at(-1) + 1;
                    if (!comeFrom[neighbor]) {
                        comeFrom[neighbor] = arr;
                        nextFrontier.push(neighbor);
                    }
                }
            }
        }
        frontier = nextFrontier;
    }
}

// Example run
let data = {
  '11100171': [0, 1, 2, 3],
  '11100060': [1, 2, 3],
  '12100062': [4],
  'aaaaaaaa': [4, 5],
  '12100012': [5, 6, 7],
  '12100011': [6, 7],
  '12100020': [7],
  '12100121': [7],
  '11100130': [8, 9],
  '11100140': [8, 9],
  '11100470': [8, 9],
  '11400080': [8, 9, 10],
  'xxxxxxxx': [9, 10]
};

let adj = createAdjacencyList(data);
let path = shortestPath(adj, 0, 10);
for (let arr of path) {
    console.log(...arr);
}