zoukankan      html  css  js  c++  java
  • Medium | 剑指 Offer 13. 机器人的运动范围 | 矩阵 + DFS递归遍历

    剑指 Offer 13. 机器人的运动范围

    地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

    示例 1:

    输入:m = 2, n = 3, k = 1
    输出:3
    

    示例 2:

    输入:m = 3, n = 1, k = 0
    输出:1
    

    提示:

    • 1 <= n,m <= 100
    • 0 <= k <= 20

    本题通过DFS遍历就就能解决。DFS遍历需要设置一个访问数组标志当前位置是否已经访问过。访问下一个位置时可以用一个4x2的数组来表示上下左右的四个方向int[][] dir = new int[][]{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};如果下一个位置可以访问, 就访问它, 不能访问或者访问过了就遍历下一个位置。

    private int[][] dir = new int[][]{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    // 访问标志数组
    private boolean[][] visit;
    private int row;
    private int colume;
    // 本题的坐标各个位数之和的最大阈值
    private int threshold;
    
    public int movingCount(int m, int n, int k) {
        this.row = m;
        this.colume = n;
        this.threshold = k;
        visit = new boolean[m][n];
        // 开始暴力DFS遍历, 
        dfs(0, 0);
        int res = 0;
        // 此时DFS遍历完成, 所有能够访问的位置已经在visit数组打上了标记, 只需要统计数量即可
        for(int i = 0; i < row; i++) {
            for (int j = 0; j < colume; j++) {
                if (visit[i][j]) {
                    res++;
                }
            }
        }
        return res;
    }
    // dfs遍历矩阵
    public void dfs(int x, int y) {
        visit[x][y] = true;
       	// DFS遍历与当前位置相邻的几个位置, 这里只需要向右和向下即可, 不需要向上和向左, 因为是从左上角出发的
        // DFS本身是可以枚举每一种可能情况的
        for(int i = 1; i < 3; i++) {
            int newx = x + dir[i][0];
            int newy = y + dir[i][1];
            if (checkCanEntry(newx, newy)) {
                dfs(newx, newy);
            }
        }
    }
    // 判断是否能够访问:1. 下标是否越界 2. 是否已经访问过 3. 坐标位数之和是否超过阈值
    public boolean checkCanEntry(int x, int y) {
        return x >= 0 && x < row && y >= 0 && y < colume && 
        !visit[x][y] && 
        getDigit(x) + getDigit(y) <= threshold;    
    }
    
    // 求某个数字的各个位数之和
    public int getDigit(int x) {
        int sum = 0;
        while(x != 0) {
            sum += x % 10;
            x /= 10;
        }
        return sum;
    }
    
  • 相关阅读:
    Spring Boot快速搭建Spring框架
    JVM内存管理机制
    开发者应该掌握的Java代码优化技能
    23种设计模式(8)-外观模式
    1823:【00NOIP提高组】方格取数
    【00NOIP提高组】单词接龙
    1821:【00NOIP提高组】乘积最大
    1820:【00NOIP提高组】进制转换
    时间复杂度比较
    hhhhh我想起来我的账号了
  • 原文地址:https://www.cnblogs.com/chenrj97/p/14281105.html
Copyright © 2011-2022 走看看