题目
An undirected, connected graph of N nodes (labeled 0, 1, 2, ..., N-1
) is given as graph
.
graph.length = N
, and j != i
is in the list graph[i]
exactly once, if and only if nodes i
and j
are connected.
Return the length of the shortest path that visits every node. You may start and stop at any node, you may revisit nodes multiple times, and you may reuse edges.
Example 1:
1 | Input: [[1,2,3],[0],[0],[0]] |
Example 2:
1 | Input: [[1],[0,2,4],[1,3,4],[2],[1,2]] |
Note:
1 <= graph.length <= 12
0 <= graph[i].length < graph.length
解法一
这周刚好学到了BFS、Dijkstra、Bellman–Ford等处理图论问题的算法,这里就能够用上了。这一题是要在无向图中找到经过了每一个节点的最短路径,可以很快想到可以用BFS算法,但是再一想,BFS算法可以用来找两点间最短路径,而这里并没有给出起点和终点,只是单纯的找到一条经过每个节点的最短路径,怎么办呢?
以往使用BFS算法时,是将节点不断加入、弹出队列,在这里我们可以换种思路,比如把从各个节点开始的路径加入、更新、弹出队列,并记录此时路径对应的长度,直到队列为空时,此时经过了所有节点的路径的长度应该被更新了许多次,达到了最小。
首先需要构建一个struct类型,代表此时的路径状态:
1 | struct state{ |
用bits来记录经过的节点:从第n号节点开始即为1 << n = 1...00
(n个0),访问完所有节点的路径状态应该是011..1
,哪一位为1即代表经过了哪一位,访问节点的邻居后的节点状态这样表示:visited | (1 << neighbour)
。
接下来是实现:
1 | int shortestPathLength(vector<vector<int>>& graph) { |
比较难想到的地方就是对路径状态进行BFS。
解法二
通过官方solution发现了第二种使用了Dynamic Programming的解法,大体上其实和BFS差不多,都是对路径状态进行操作。
解法如下:
1 | int shortestPathLength(vector<vector<int>>& graph) { |
可以看到,这种解法是通过多重循环,对dist中每一种路径状态进行更新,最后取都是经过每个节点的路径中最短的一条。