图论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;     
    }
}
相关推荐
y = xⁿ1 分钟前
20天速通LeetCode day08:关于栈
算法·leetcode·职场和发展
Shadow(⊙o⊙)12 分钟前
专题二滑动窗口
数据结构·算法
tankeven20 分钟前
HJ181 相差不超过k的最多数
数据结构·c++·算法
XWalnut38 分钟前
LeetCode刷题 day13
数据结构·算法·leetcode
小马_xiaoen1 小时前
前端虚拟列表(Virtual List)从原理到实战:海量数据渲染终极方案
前端·数据结构·list
炽烈小老头1 小时前
【每天学习一点算法 2026/04/17】多数元素
数据结构·学习·算法
云泽8081 小时前
第十五届蓝桥杯大赛软件赛省赛C/C++大学B组
c语言·c++·算法·蓝桥杯
大模型最新论文速读1 小时前
VQKV:KV Cache 压缩 82% 性能几乎不降
人工智能·深度学习·算法·机器学习·自然语言处理
yongui478341 小时前
基于MSP430和Zigbee技术的煤矿综合监控系统设计与实现
算法
Ww.xh2 小时前
ESP8266连接AI大模型完整指南
人工智能·算法·语言模型