LeetCode 847 Shortest Path Visiting All Nodes

13 篇文章 0 订阅

思路

由于是求简单图最小路径问题,所以可以用BFS来解决(最短路模版,每次遍历一层节点)。可以发现,一条路径的最终的长度只与最后一个经过的点有关系,跟访问前面节点的顺序没有关系。所以我们可以用一个二维visit数组记录每种路线终点所对应的路线,避免重复搜索;BFS的队列中存储一维数组node,node[0]:最后一个节点,node[1]:路线对应的整数【在这里将路线压缩成一个整数,原理是使用二进制的思想,从右向左代表0~n位,比如1101就是路线0-2-3】

在程序中一旦找到第一个能遍历所有节点的路线就返回步数,这保证了程序的正确性:寻找最短的步数。

位操作:(1)1<<len:所有可能的路线代表的整数=2len
(2)(1<<len)-1:所有位都是1的情况,比如len=3,(1<<3) - 1 = (1000)2 - 1 = (111)2
(3)int nextState = state | (1 << next) : 将next那个节点加入到路线代表的整数中,比如当前state=(001)2, next为节点2,于是加入后nextState = (101)2.

复杂度

时间复杂度 O ( n ∗ 2 n ) O(n*2^n) O(n2n):从每一个节点(n)出发都有2^n种路径(从二进制可以看出)
空间复杂度 O ( n ∗ 2 n ) O(n*2^n) O(n2n)

代码

class Solution {
    public int shortestPathLength(int[][] graph) {
        // bfs
        int len = graph.length;
        // [endPoint][state]
        boolean[][] visit = new boolean[len][1 << len];
        Queue<int[]> queue = new LinkedList<>();
        int goal = (1 << len) - 1;
        
        for (int i = 0; i < len; i++) {
            queue.offer(new int[]{i, 1 << i});
        }
        
        int step = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            while (size-- > 0) {
                int[] node = queue.poll();
                int endWith = node[0], state = node[1];
                if (goal == state) {
                    return step;
                }
                for (int next : graph[endWith]) {
                    int nextState = state | (1 << next);
                    if (visit[next][nextState]) {
                        continue;
                    }
                    queue.offer(new int[]{next, nextState});
                    visit[next][nextState] = true;
                }
            }
            step++;
        }
        return step;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值