图论17(Leetcode864.获取所有钥匙的最短路径)

用二进制表示获得的钥匙,假设n=钥匙个数

000000000代表没有钥匙,0000000001代表有idx为1的钥匙,0000000011代表有idx=1,2的钥匙

(这方法巧妙又复杂..

代码:

java 复制代码
class Solution {
    static int[][] dirs = {{-1,0},{1,0},{0,-1},{0,1}};
    public int shortestPathAllKeys(String[] grid) {
        int m = grid.length, n = grid[0].length();
        int startx = 0,starty = 0;
        Map<Character, Integer> keyToIndex = new HashMap<>();
        //存钥匙的字母和对应的idx序号
        for(int i=0;i<grid.length;i++){
            for(int j=0;j<grid[i].length();j++){
                if(grid[i].charAt(j)=='@'){
                    startx = i;
                    starty = j;
                }else if(Character.isLowerCase(grid[i].charAt(j))){
                    if(!keyToIndex.containsKey(grid[i].charAt(j))){
                        int idx = keyToIndex.size();
                        keyToIndex.put(grid[i].charAt(j), idx);
                    }                    
                }
            }
        }
        Queue<int[]> queue = new ArrayDeque<int[]>();
        int[][][] dist = new int[m][n][1<<keyToIndex.size()];
        //第三维是2的size次方 列举钥匙的所有可能
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                Arrays.fill(dist[i][j],-1);
            }
        } 
        queue.offer(new int[]{startx,starty,0});
        dist[startx][starty][0] = 0;
        while(!queue.isEmpty()){
            int[] arr = queue.poll();
            int x = arr[0],y = arr[1],mask = arr[2];//mask是钥匙的排列
            for(int i=0;i<4;i++){
                int nx = x + dirs[i][0];
                int ny = y + dirs[i][1];
                if(nx>=0 && nx<m && ny>=0 && ny<n &&grid[nx].charAt(ny)!='#'){
                    if(grid[nx].charAt(ny)=='.'||grid[nx].charAt(ny)=='@'){
                        if(dist[nx][ny][mask] == -1){
                            dist[nx][ny][mask] = dist[x][y][mask]+1;
                            queue.offer(new int[]{nx,ny,mask});
                        }
                    }else if(Character.isLowerCase(grid[nx].charAt(ny))){
                        int idx = keyToIndex.get(grid[nx].charAt(ny));
                        if(dist[nx][ny][mask|(1<<idx)] == -1){
                            dist[nx][ny][mask|(1<<idx)] = dist[x][y][mask]+1;
                            if((mask|(1<<idx))==(1<<keyToIndex.size())-1){
                                return dist[nx][ny][mask|(1<<idx)];
                            }
                            queue.offer(new int[]{nx,ny,mask|(1<<idx)});
                        }
                    }else{
                        int idx = keyToIndex.get(Character.toLowerCase(grid[nx].charAt(ny)));
                        if((mask&(1<<idx))!=0&&dist[nx][ny][mask]==-1){
                            dist[nx][ny][mask] = dist[x][y][mask]+1;
                            queue.offer(new int[]{nx,ny,mask});
                        }
                    }
                }
            }

        }  
        return -1;     
    }
}
相关推荐
源代码•宸28 分钟前
Leetcode—620. 有趣的电影&&Q3. 有趣的电影【简单】
数据库·后端·mysql·算法·leetcode·职场和发展
2301_800256111 小时前
地理空间数据库中的CPU 和 I/O 开销
数据库·算法·oracle
一个不知名程序员www2 小时前
算法学习入门---结构体和类(C++)
c++·算法
XFF不秃头4 小时前
力扣刷题笔记-旋转图像
c++·笔记·算法·leetcode
王老师青少年编程4 小时前
csp信奥赛C++标准模板库STL案例应用3
c++·算法·stl·csp·信奥赛·lower_bound·标准模版库
有为少年5 小时前
Welford 算法 | 优雅地计算海量数据的均值与方差
人工智能·深度学习·神经网络·学习·算法·机器学习·均值算法
Ven%5 小时前
从单轮问答到连贯对话:RAG多轮对话技术详解
人工智能·python·深度学习·神经网络·算法
山楂树の5 小时前
爬楼梯(动态规划)
算法·动态规划
谈笑也风生5 小时前
经典算法题型之复数乘法(二)
开发语言·python·算法