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

news/2024/7/15 19:47:36 标签: 图论, 算法, 数据结构

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

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

(这方法巧妙又复杂..

代码:

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;     
    }
}


http://www.niftyadmin.cn/n/5037355.html

相关文章

Java下打印九九乘法表

这个算法是基于打直角三角型演变而来&#xff0c;代码如下&#xff1a; public class MyWork {public static void main(String[] args) {for (int i 1; i < 10; i) {for (int j 1; j < i; j) {System.out.print(j "x" i "" i*j "\t&qu…

FreeRTOS移植以及核心功能

文章目录 freertos和ucos区别&#xff0c;优缺点比较移植步骤核心功能内存管理&#xff08;5种内存管理策略&#xff09;FreeRTOS任务调度算法有三种时间管理通信管理 栈管理 freertos和ucos区别&#xff0c;优缺点比较 FreeRTOS&#xff08;Free Real-Time Operating System&…

【Vue】用Vue代码详细介绍computed计算属性的用法

当需要进行一些复杂的、依赖于其他属性的计算时&#xff0c;可以使用计算属性来处理这些计算&#xff0c;而不是在模板中直接进行计算。以下是使用Vue实现计算属性的示例&#xff1a; <div id"app"><p>商品价格&#xff1a;{{ price }} 元</p><…

ext4文件系统镜像制作

(1)制作镜像,用dd工具创建一定大小空的镜像文件. dd if/dev/zero oftest.img bs1M count300 bs1M:表示每块读写1M的数据 count300:拷贝块的数量(2) 可以查看制作的镜像 hexdump -C test.img ll test.img (3)格式化镜像 mkfs.ext4 test.img (4)创建挂载点 mkdir mount_tes…

G. Best ACMer Solves the Hardest Problem

Problem - G - Codeforces 有一天&#xff0c;一位优秀的ACMer将离开这个领域&#xff0c;面对新的挑战&#xff0c;就像前辈们所做的一样。他们中的一些人接管了家族企业&#xff0c;一些人在失业的边缘挣扎。一些人有勇气展示自己&#xff0c;成为专业的Ingress玩家&#xff…

jira查询user详细信息

官方文档如下&#xff1a; The Jira Cloud platform REST API 示例代码如下&#xff1a; public static void getUser() throws UnirestException {// This code sample uses the Unirest library:// http://unirest.io/java.htmlHttpResponse<JsonNode> response U…

vue监听路由变化

//监听watch: {//监听路由$route (to, from) { //监听路由是否变化console.log(to.path);if(to.path "/Jindex/JuserindexAdd"){}}}, 升级 //监听watch: {//监听路由$route (to, from) { //监听路由是否变化let urlPath [/order/order,/order/listDate];console.l…

扩散模型基本原理

1 生成式模型基本思想 使用模型模拟真实世界的图像分布&#xff0c;可以学习神经网络模型&#xff0c;使其将标准正态分布的每个点映射到真实图像分布的点 2 扩散模型 2.1 正向过程 从原始图像逐步添加噪声&#xff0c;最终得到近似完全噪声的图像 q ( x t ∣ x t − 1 ) …