存在一个由 n 个节点组成的无向连通图,图中的节点按从 0n - 1 编号。

给你一个数组 graph 表示这个图。其中,graph[i] 是一个列表,由所有与节点 i 直接相连的节点组成。

返回能够访问所有节点的最短路径的长度。你可以在任一节点开始和停止,也可以多次重访节点,并且可以重用边。

 

示例 1:

输入:graph = [[1,2,3],[0],[0],[0]]
输出:4
解释:一种可能的路径为 [1,0,2,0,3]

示例 2:

输入:graph = [[1],[0,2,4],[1,3,4],[2],[1,2]]
输出:4
解释:一种可能的路径为 [0,1,4,2,3]

 

提示:

  • n == graph.length
  • 1 <= n <= 12
  • 0 <= graph[i].length < n
  • graph[i] 不包含 i
  • 如果 graph[a] 包含 b ,那么 graph[b] 也包含 a
  • 输入的图总是连通图
Related Topics
  • 位运算
  • 广度优先搜索
  • 动态规划
  • 状态压缩
  • \n
  • 👍 190
  • 👎 0
  • 题解

    
    import java.util.LinkedList;
    import java.util.Queue;
    
    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        public int shortestPathLength(int[][] graph) {
            int length = graph.length;
    
            Queue<int[]> queue = new LinkedList<>();
            boolean[][] visited = new boolean[length][1<<length];
            for (int i = 0; i < length; i++) {
                //  出发点,经过状态(状态压缩),步数
                queue.offer(new int[]{i,1<<i,0});
                visited[i][1<<i] = true;
            }
            while (!queue.isEmpty()){
                int[] current = queue.poll();
                int index = current[0];
                int status = current[1];
                int steps = current[2];
    
                if (status == (1 << length)-1){
                    //所有点都被访问过了
                    return steps;
                }
                for (int nextIndex : graph[index]) {
                    int nextIndexStatus = status | (1 << nextIndex);
                    if (!visited[nextIndex][nextIndexStatus]) {
                        queue.offer(new int[]{nextIndex, nextIndexStatus, steps + 1});
                        visited[nextIndex][nextIndexStatus] = true;
                    }
    
                }
    
    
    
            }
    
            return 0;
    
    
        }
    }
    //leetcode submit region end(Prohibit modification and deletion)