• leetcode.864 获取所有钥匙的最短路径 - bfs+状态压缩+最短路+位运算


    864. 获取所有钥匙的最短路径

    困难 看着三叶姐的题解理解的 理解上没什么大问题 主要卡在位运算

    其他思路是传统的bfs做法

    第一步:解决钥匙问题

    因为要求捡完所有钥匙最短路径,锁可以不开完,但钥匙要捡完

    • 题目规定【钥匙数量不超过6,按字母顺序排列】,我们可以用二进制数state来表示当前收集到钥匙的情况
    • 如果state的二进制中第k位为1,代表编号k的钥匙已被收集
    • 如果state的二进制中第k为为0,代表编号k的钥匙未被收集

    通过位运算可以进行钥匙检测更新钥匙收集状态

    • 钥匙检测:(state>>k)&1  也就是取出第k位,判断是否为1 ,是即为拥有编号k的钥匙
    • 更新钥匙收集状态:state|=1< 将state的第k位设置为1,代表收集到编号为k的钥匙

    第二步:准备工作

    • pos[x][y][state]   记录的是当前步的最短路 一开始要都初始化所有的点的pos为无穷大
    • dirs[][]   方向数组,控制上下左右移动

    第三步:BFS 

    • 首先将起点@入队  并遍历全图  记录钥匙总数key
    • 由起点开始上下左右扩展 如果越界、遇到锁没钥匙、走的步数大于之前的最短路、撞墙四种情况 continue 即这条路走不通 放弃
    • 遇到钥匙时,需要更新钥匙状态state
    • 如果钥匙状态state每一位全为1 说明钥匙收集完毕 只要再走一步(step+1)就完成任务
    • 将当前点入队 继续下一轮扩展
    1. class Solution {
    2. static int N=30,K=6,INF=0x3f3f3f3f;
    3. static int[][] dirs=new int[][]{{1,0},{-1,0},{0,-1},{0,1}};
    4. //x y代表坐标,s代表当前钥匙状态 pos表示当前步的最短路
    5. static int[][][] pos=new int[N][N][1<
    6. public int shortestPathAllKeys(String[] g)
    7. {
    8. Deque<int[]> q=new ArrayDeque<>();
    9. int m=g.length,n=g[0].length();
    10. int key=0;
    11. for(int i=0;i
    12. for(int j=0;j
    13. {
    14. Arrays.fill(pos[i][j],INF); //初始化每个格最短距离为无穷大
    15. char ch=g[i].charAt(j);
    16. if(ch=='@')
    17. {
    18. q.offerLast(new int[]{i,j,0});
    19. pos[i][j][0]=0;
    20. }else if(ch>='a'&&ch<='z') key++;
    21. }
    22. while(!q.isEmpty())
    23. {
    24. int[] t=q.pollFirst();
    25. int x=t[0],y=t[1],state=t[2];
    26. int step=pos[x][y][state];
    27. for(int[] dir:dirs)
    28. {
    29. int nx=x+dir[0],ny=y+dir[1];
    30. if(nx<0||nx>=m||ny<0||ny>=n) continue;
    31. char c=g[nx].charAt(ny);
    32. if(c=='#') continue;
    33. if((c>='A'&&c<='Z')&&(state>>(c-'A')&1)==0) continue; //如果遇到锁但是没有钥匙 跳过
    34. int next=state; //因为state在for循环外定义的,所以不能直接更改,需要先定义变量接收
    35. if(c>='a'&&c<='z')
    36. next|=1<<(c-'a'); //如果是钥匙 则更新状态
    37. if(next==(1<1) return step+1; //如果钥匙状态全为1 说明再走一步钥匙搜集完毕
    38. if(step+1>=pos[nx][ny][next]) continue; //如果之前有更短的走法则跳过不走
    39. pos[nx][ny][next]=step+1;
    40. q.offerLast(new int[]{nx,ny,next});
    41. }
    42. }
    43. return -1;
    44. }
    45. }

  • 相关阅读:
    电动工具——电钻驱动方案设计
    vue--前端路由及vue-router两种模式
    何为智能指针以及QT中的智能指针
    将 JavaScript 字符串隐藏为数字的 4 种简单方法以及如何删除浮点数上的尾随零
    年薪达不到23.5万全额退款 | 人工智能核心能力培养计划
    概统 | 一图总结特殊积分之伽马函数
    一图看懂CodeArts Governance 三大特性,带你玩转开源治理服务
    gunicorn参数说明英文及译文
    CC1101 一款低功耗sub- 1ghz收发器芯片 适用于无线遥控智能家居
    2022年最新宁夏建筑安全员模拟题库及答案
  • 原文地址:https://blog.csdn.net/weixin_61639349/article/details/127795473