JavaInterview JavaInterview
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)

『Java面试+Java学习』
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)
  • 指南
  • 简历

  • Java

  • 面试

  • 算法

  • algorithm
  • leetcode
JavaInterview.cn
2024-03-24
目录

获取所有钥匙的最短路径Java

文章发布较早,内容可能过时,阅读注意甄别。

# 题目

给定一个二维网格 grid ,其中:

  • '.' 代表一个空房间
  • '#' 代表一堵墙
  • '@' 是起点
  • 小写字母代表钥匙
  • 大写字母代表锁 我们从起点开始出发,一次移动是指向四个基本方向之一行走一个单位空间。我们不能在网格外面行走,也无法穿过一堵墙。如果途经一个钥匙,我们就把它捡起来。除非我们手里有对应的钥匙,否则无法通过锁。

假设 k 为 钥匙/锁 的个数,且满足 1 <= k <= 6,字母表中的前 k 个字母在网格中都有自己对应的一个小写和一个大写字母。换言之,每个锁有唯一对应的钥匙,每个钥匙也有唯一对应的锁。另外,代表钥匙和锁的字母互为大小写并按字母顺序排列。

返回获取所有钥匙所需要的移动的最少次数。如果无法获取所有钥匙,返回 -1 。

示例 1:

lc-keys2.jpg

输入:grid = ["@.a..","###.#","b.A.B"]
输出:8
解释:目标是获得所有钥匙,而不是打开所有锁。

示例 2:

lc-key2.jpg

输入:grid = ["@..aA","..B#.","....b"]
输出:6

示例 3:

lc-keys3.jpg

输入: grid = ["@Aa"]
输出: -1

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 30
  • grid[i][j] 只含有 '.', '#', '@', 'a'-'f' 以及 'A'-'F'
  • 钥匙的数目范围是 [1, 6]
  • 每个钥匙都对应一个 不同 的字母
  • 每个钥匙正好打开一个对应的锁

# 思路

Deque

# 解法


class Solution {
    public int shortestPathAllKeys(String[] grid) {
        //四个方向
        int[] dirs = {-1, 0, 1, 0, -1};
        int m = grid.length, n = grid[0].length();
        int keyCount = 0, x = 0, y = 0, res = 0;
        //遍历字符串数组,查找钥匙数
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                char c = grid[i].charAt(j);
                //任务钥匙数量统计
                if (Character.isLowerCase(c)) keyCount++;
                else if (c == '@') {
                    //出发点坐标
                    x = i;
                    y = j;
                }
            }
        }
        //GPS!存储要走的路!
        Deque<int[]> deque = new LinkedList<>();
        //先把出发点放进去
        deque.offer(new int[]{x, y, 0});
        boolean[][][] flag = new boolean[m][n][1 << keyCount];
        flag[x][y][0] = true;
        while (!deque.isEmpty()) {
            for (int num = deque.size(); num > 0; num--) {
                int[] cur = deque.poll();
                int i = cur[0], j = cur[1], state = cur[2];
                //哎嘿!找到钥匙了!
                if (state == (1 << keyCount) - 1) return res;
                //woc!少了几把!接着找!
                for (int k = 0; k < 4; k++) {
                    int xDir = i + dirs[k], yDir = j + dirs[k + 1];
                    //别越界了!
                    if (xDir >= 0 && xDir < m && yDir >= 0 && yDir < n) {
                        char c = grid[xDir].charAt(yDir);
                        //撞墙了!锁门了!
                        if (c == '#' || (Character.isUpperCase(c) && ((state >> (c - 'A') & 1) == 0))) continue;
                        int temp = state;
                        //woc!key!
                        if (Character.isLowerCase(c))
                            //揣兜里!
                            temp |= (1 << (c - 'a'));
                        //啊!这里没来过!加入我的gps数据
                        if (!flag[xDir][yDir][temp]) {
                            flag[xDir][yDir][temp] = true;
                            deque.offer(new int[]{xDir, yDir, temp});
                        }
                    }
                }
            }
            res++;
        }
        //西八!没找全!
        return -1;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

# 总结

  • 分析出几种情况,然后分别对各个情况实现
微信 支付宝
最近更新
01
1686. 石子游戏VI Java
08-18
02
1688. 比赛中的配对次数 Java
08-18
03
1687. 从仓库到码头运输箱子 Java
08-18
更多文章>
Theme by Vdoing | Copyright © 2019-2025 JavaInterview.cn
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式