• 剑指66.机器人的运动范围


    题目描述

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

    思路

    与《矩阵中的路径》类似,但这道题不需要回溯,因为如果满足条件一定可以走到。而《矩阵中的路径》如果路径走不通,需要回溯。

    思路1:通过递归的去查找某一个下标位置的两个方向即可(要么往右要么往下),在到达某一个位置的时候,判断是否越界,是否被访问过,是否满足数位之和小于k        (最优解)

    思路2:逐个遍历每一个方格,判断数位之和是否小于等于k,并且判断当前位置能否由 上边的位置 和 左边的位置 走来即可。   (如果k=0时,仍需要不断判断,该方法效率较低)

    ☆☆解法1

    public class Solution {
        private int sum = 0;
        public int movingCount(int threshold, int rows, int cols) {
            boolean[][] vis = new boolean[rows][cols];
            solve(0,0,rows,cols,threshold,vis);
            return sum;
        }
        // 牢记如何求位数和!!
        private int cal(int num){
            int res = 0;
            while (num > 0){
                res += num % 10;
                num /= 10;
            }
            return res;
        }
        private void solve(int x, int y, int rows, int cols, int k, boolean[][] vis) {
            if (x < 0 || y < 0 || x >= rows || y >= cols || vis[x][y] || (cal(x) + cal(y) > k)){
                return;
            }
            // 当前位置(x,y)是可以走的,那么就从当前位置往右下移动即可。
            vis[x][y] = true;
            sum++;
            solve(x,y+1,rows,cols,k,vis); //
            solve(x+1,y,rows,cols,k,vis); //// 既然不用回溯,就不需要递归x-1和y-1的坐标了,因为从左上角出发,每次只需要往右和往下搜索
    //        solve(x-1,y,rows,cols,k,vis);
    //        solve(x,y-1,rows,cols,k,vis);
        }
    }

    ☆解法2

    public class Solution {
        public int movingCount(int threshold, int rows, int cols) {
            int sum = threshold >= 0 ? 1 : 0;
            boolean[][] vis = new boolean[rows][cols];
            vis[0][0] = true;
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < cols; j++) {
                    if ((cal(i) + cal(j)) <= threshold){
                        // 判断能否从上边走过来
                        if (i-1 >= 0 && vis[i-1][j]){
                            sum++;
                            vis[i][j] = true;
                            // 判断能否从左边走过来
                        }else if (j-1 >= 0 && vis[i][j-1]){
                            sum++;
                            vis[i][j] = true;
                        }
                    }
                }
            }
            return sum;
        }
        private int cal(int num){
            int res = 0;
            while (num > 0){
                res += num % 10;
                num /= 10;
            }
            return res;
        }
    }
     
  • 相关阅读:
    js识别键盘操作
    抽奖活动 算法设计
    Eureka 配置项说明
    manjaro 更新chrome报签名错误
    manjaro系统上使用asdf安装php注意事项
    Failed to load config "react-app" to extend from.
    YarnV2 install
    银河麒麟安装达梦数据库失败Unable to load native library: libnsl.so.1: cannot open shared object file: No such file or directory
    Net5中使用Swagger
    编译Windows 版本的Redis 6.x
  • 原文地址:https://www.cnblogs.com/HuangYJ/p/13673072.html
Copyright © 2020-2023  润新知