zoukankan      html  css  js  c++  java
  • [leetCode]1036. 逃离大迷宫

    在这里插入图片描述

    广度优先搜索

    class Solution {
        // 定义一个方向数组
        static int[][] directions = new int[][]{{0, 1}, {1, 0}, {-1, 0},{0, -1}};
        // X,Y的上限
        static int limit = (int)1e6;
        public boolean isEscapePossible(int[][] blocked, int[] source, int[] target) {
            if (blocked.length == 0) return true;
            // 使用一个哈希表,保存被封锁的网格
            Set<String> blocks = new HashSet<>();
            for (int[] block : blocked) {
                blocks.add(block[0] + ":" + block[1]);
            }
            /* 因为只迭代20000步, 如果是目标点在被封锁的区域内正着跑也可以到
            20000步但是到不了目标点, 正反都跑一次才保证能到达目标点*/
            // 目标的有可能被全部包围
            return bfs(source, target, blocks) && bfs(target, source, blocks);
        }
    
        public boolean bfs(int[] source, int[] target, Set<String> blocks) {
            // 使用一个哈希表保存已经走过的节点
            Set<String> seen = new HashSet<>();
            seen.add(source[0] + ":" + source[1]);
            // 使用一个队列保存当前能走的网格坐标
            Queue<int[]> queue = new LinkedList<>();
            queue.add(source);
            while (!queue.isEmpty()) {
                // 当前坐标
                int[] cur = queue.poll();
                // 遍历方向数组directions
                for (int[] dir : directions) {
                    // (nextX, nextY)为下一个网格点坐标
                    int nextX = dir[0] + cur[0];
                    int nextY = dir[1] + cur[1];
                    // 如果坐标越界跳过这个方向
                    if (nextX < 0 || nextY < 0 || nextX > limit || nextY > limit) continue;
                    // 用于哈希表查询,如果该坐标已经走过或者被封锁则走下一个方向
                    String key = nextX + ":" + nextY;
                    if (seen.contains(key) || blocks.contains(key)) continue;
                    // 走到了目标点返回true
                    if (nextX == target[0] && nextY == target[1]) return true;
                    queue.offer(new int[]{nextX, nextY});
                    // 添加到已走过的点中
                    seen.add(key);
                }
                // 因为 blocked 的 length 是 200
                // 如果使用这 200 个 block 可以围成最大的区域是 19900,如下:
                /*
                    0th      _________________________
                            |O O O O O O O X
                            |O O O O O O X
                            |O O O O O X
                            |O O O O X
                            .O O O X
                            .O O X
                            .O X
                    200th   |X
                从上面可以计算出 block(即 X)可以围城的最大区域(是一个角的三角形),大小计算如下:
                1 + 2 + 3 + 4 + ... + 199 = (1 + 199) * 199 / 2 = 19900
                这里我们向上取整为 20000。
                */
                // 也就是说,如果迭代了 20000 步还能继续走的话,那么是肯定可以到达 target 的
                if (seen.size() > 19900) return true;
            }
            return false;
        }
        
    }
    
  • 相关阅读:
    POJ10024873279
    javascript中转为二进制
    javascript画图库
    javascript返回多个参数
    单引号,双引号,javascript,HTML,转义字符
    onKeypress对中文无效
    javascript参数传址与传值
    关于JS中引用其它JS的问题
    JavaScript中可建立自己的库
    路由表详解
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13859896.html
Copyright © 2011-2022 走看看