图论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;     
    }
}
相关推荐
luckys.one2 小时前
第9篇:Freqtrade量化交易之config.json 基础入门与初始化
javascript·数据库·python·mysql·算法·json·区块链
~|Bernard|3 小时前
在 PyCharm 里怎么“点鼠标”完成指令同样的运行操作
算法·conda
战术摸鱼大师3 小时前
电机控制(四)-级联PID控制器与参数整定(MATLAB&Simulink)
算法·matlab·运动控制·电机控制
Christo33 小时前
TFS-2018《On the convergence of the sparse possibilistic c-means algorithm》
人工智能·算法·机器学习·数据挖掘
好家伙VCC4 小时前
数学建模模型 全网最全 数学建模常见算法汇总 含代码分析讲解
大数据·嵌入式硬件·算法·数学建模
liulilittle6 小时前
IP校验和算法:从网络协议到SIMD深度优化
网络·c++·网络协议·tcp/ip·算法·ip·通信
bkspiderx7 小时前
C++经典的数据结构与算法之经典算法思想:贪心算法(Greedy)
数据结构·c++·算法·贪心算法
中华小当家呐9 小时前
算法之常见八大排序
数据结构·算法·排序算法
沐怡旸9 小时前
【算法--链表】114.二叉树展开为链表--通俗讲解
算法·面试
tju新生代魔迷9 小时前
数据结构:双向链表
数据结构·链表