美文网首页
leetcode 864

leetcode 864

作者: Wilbur_ | 来源:发表于2021-01-26 02:07 被阅读0次

864. Shortest path to find all keys

这道题难点在于要用一个class 来表示当前的状态,如果用普通的BFS来做的话,你会因为向外扩散的时候直接把所有的key全部放到当前bfs的范围里面了,但是这样是错误的,因为每条路径是单独的,所以要用一个class/object来表示,这样才能记录你每条路所得到的钥匙,然后通过bfs的特性来找到最短路径。这里用Set来存储每条路径的唯一性。而set里面用的数据结构是String,可能是因为更方便一点吧?因为"x + " " + y + " " + key"这种结构变成hash的话更方便,如果直接用set来存state可能要自己写hash function?key本身就是用数字来存储当前得到的钥匙的状态。这里用了bit mask,所以比较高级。但是本质上就是通过 key |= c - 'a' 来把当前钥匙记录下来,c = start.charAt(i*m+j) c就是当前节点的character
每次取出当前队列的State的时候,检查State cur.key == (1 << keyCount) - 1
这里1<<keyCount 是把1 向左移动keyCount次,这样减去1就能够得到所有key的表示方式,比如keyCount=3,那么1<<keyCount - 1 == 0111
就表示0, 1, 2号钥匙我们已经拿到手了。

class ShortestPathAllKeys {
    int[][] dirs = new int[][] {{0,1}, {0,-1}, {1,0}, {-1,0}};
    public int shortestPathAllKeys(String[] grid) {
        StringBuilder sb = new StringBuilder();
        int n = grid.length, m = grid[0].length(), keyCount = 0, lockCount = 0;
        // System.out.println("n: " + n + " m " + m);
        for (String s : grid) {
            for (int i = 0; i < s.length(); i++) {
                char c = s.charAt(i);
                if (c - 'a' >= 0 && c-'a' < 26) {
                    keyCount++;
                } else if (c - 'A' >= 0 && c - 'A' <= 25) {
                    lockCount++;
                }
            }
            sb.append(s);
        }
        String startStr = sb.toString();

        int start = startStr.indexOf('@');
        State startState = new State(start / m, start % m, 0);
        Queue<State> q = new LinkedList<>();
        Set<String> visited = new HashSet<>();
        q.add(startState);
        visited.add(start / m + " " + start % m + " " + 0);
        int step = 0;
        while(!q.isEmpty()) {
            int size = q.size();
            for (int k = 0; k < size; k++) {
                State cur = q.poll();
                if (cur.key == (1 << keyCount) - 1) return step;
                for (int[] dir : dirs) {
                    int i = cur.x + dir[0], j = cur.y + dir[1], key = cur.key;
                    if (i >= 0 && i < n && j >= 0 && j < m && startStr.charAt(i*m+j) != '#') {
                        char c = startStr.charAt(i*m+j);
                        if (c - 'A' >= 0 && c - 'A' < 26) {
                            //it is a lock, check if we have the key
                            if ((key >> (c - 'A') & 1) == 0) {
                                continue;
                            }
                        } else if (c - 'a' >= 0 && c - 'a' < 26) {
                            // it is a key
                            key |= (1 << (c - 'a'));
                        }
                        if (visited.add(i + " " + j + " " + key)) q.add(new State(i, j, key));
                    }
                }
            }
            step++;
        }
        return -1;
    }
    class State {
        int x, y, key;
        public State(int x, int y, int key) {
            this.x = x;
            this.y = y;
            this.key = key;
        }
    }
}

相关文章

  • leetcode 864

    864. Shortest path to find all keys 这道题难点在于要用一个class 来表示当...

  • Leetcode#864 Shortest Path to Ge

    题目大意 给定一个二维的平面迷宫,其中@表示出发点,.表示平地可正常通行,#表示墙壁不可通行。 A-F表示锁,需要...

  • 864

    清晨,我被一阵“叽叽喳喳”声吵醒了。走到窗前一看,原来是一群小鸟在窗下那高大的山楂树上“开会”呢! ...

  • 864

    2020 01 27 星期一 亲子日记第 864 贾欣怡老爸 今天是大年初三了,按照以往的惯例今天还是...

  • 864

    昨天没写,其实在昨天零点前我是记得的,但是我就是不想动。 一旦有放弃的念头并且有了第一次以后,想要放弃就很简单了。...

  • ④-864

    ③[https://www.jianshu.com/p/dfa381f6277f] 所以作者推荐当我们面对一些不得...

  • Назидание сыну, отдаваемому в

    Примечания: Пэй Сю (裴休 791-864) ― известный государственн...

  • 864天

    何颖颖坚持读书️ 864天 《行动孕育希望——焦点解决晤谈在自杀和危机干预中的应用》第9章:147—156页 和青...

  • 日记864

    2022年4月30日 星期六 晴 今天是周六,五一假期的第一天,早上睡到了六点半,给儿子放了个小假-睡到了七点。看...

  • 864书屋

    下午本来计划出去打球,可是太热了,附近的学校又凉快的地方,但没去问让不让外边的人进去,所以就没去成,刚刚,去发现了...

网友评论

      本文标题:leetcode 864

      本文链接:https://www.haomeiwen.com/subject/ghvwzktx.html