【剑指offer】24. 机器人的运动范围(java选手)

news/2024/7/20 20:15:57 标签: 机器人, java, 深度优先

题目链接

题目链接

题目描述

地上有一个 m 行和 n列的方格,横纵坐标范围分别是 0∼m−1 和 0∼n−1。

一个机器人从坐标 (0,0) 的格子开始移动,每一次只能向左,右,上,下四个方向移动一格。

但是不能进入行坐标和列坐标的数位之和大于 k 的格子。

请问该机器人能够达到多少个格子?

注意:
0<=m<=50
0<=n<=50
0<=k<=100

样例1 输入:k=7, m=4, n=5 输出:20

样例2 输入:k=18, m=40, n=40 输出:1484

解释:当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。
但是,它不能进入方格(35,38),因为3+5+3+8 = 19。

题目考察知识点

图论!
深搜or光搜
当前节点可以达到的节点为上下左右四个方向

解题代码

深搜dfs

递归实现

java">class Solution {
    // 深度优先
    // 在确定完是否满足条件后,[先加结果,然后标为已走],然后再进行dfs
    
    int result;
    // 可以走的方向
    int dir[][] = {{-1,0},{1,0},{0,1},{0,-1}};
    public int movingCount(int threshold, int rows, int cols)
    {
        // 判断临界情况,也就是rows和cols都为0
        if(rows == 0 || cols == 0){
            return 0;
        }
        
        // 判断是否走过
        boolean[][] used = new boolean[rows][cols];
        result = 0;
        
        // 判断0,0是否符合条件
        if(!judge(0,0,threshold))   return 0;
        
        result ++;
        used[0][0] = true;
        dfs(0, 0, rows, cols, threshold, used);
        return result;
    }
    
    // 深度优先
    public void dfs(int inow, int jnow, int rows, int cols, int threshold, boolean[][] used){
        for(int i = 0; i < 4; i ++){
            int inext = inow + dir[i][0];
            int jnext = jnow + dir[i][1];
            if(inext >= 0 && inext < rows && jnext >=0 && jnext < cols){
                // 满足条件,才进行下一个dfs
                if(used[inext][jnext]==false && judge(inext, jnext, threshold)){
                    result ++;
                    used[inext][jnext] = true;
                    dfs(inext, jnext, rows, cols, threshold, used);
                }
            }
        }
    }
    
    // 是否满足条件
    public boolean judge(int i, int j, int threshold){
        int now = 0;
        while(i != 0){
            now += i % 10;
            i = i / 10;
        }
        while(j != 0){
            now += j % 10;
            j = j / 10;
        }
        // 不满足
        if(now > threshold){
            return false;
        }else{
            return true;
        }
    }
}

注意注意!!!

  • used数组是必须要有的!标识一下当前哪些格子被判断过了
  • 判断临界条件
    • 特别是!哪个rows和cols都为0的情况
  • 判断完是否符合条件再去进行dfs更容易

广搜bfs

队列实现
队列不为空的时候一直循环
符合条件的进入队列

java">class Solution {
    // 广度优先
    // 在确定完是否满足条件后,[先加结果,然后标为已走],然后再进队列
    
    int result;
    // 可以走的方向
    int dir[][] = {{-1,0},{1,0},{0,1},{0,-1}};
    public int movingCount(int threshold, int rows, int cols)
    {
        // 判断临界情况,也就是rows和cols都为0
        if(rows == 0 || cols == 0){
            return 0;
        }
        
        // 判断是否走过
        boolean[][] used = new boolean[rows][cols];
        result = 0;
        
        bfs(rows, cols, threshold, used);
        return result;
    }
    
    // 广度优先
    public void bfs(int rows, int cols, int threshold, boolean[][] used){
        Deque<int[]> deque = new LinkedList<>();
        
        if(judge(0, 0, threshold)){
            deque.push(new int[]{0, 0});
            used[0][0] = true;
            result ++;
        }
        
        while(!deque.isEmpty()){
            int[] now = deque.pop();
            int inow = now[0];
            int jnow = now[1];
            for(int i = 0; i < 4; i ++){
                int inext = inow + dir[i][0];
                int jnext = jnow + dir[i][1];
                if(inext >= 0 && inext < rows && jnext >=0 && jnext < cols){
                    // 满足条件,才进入队列
                    if(used[inext][jnext]==false && judge(inext, jnext, threshold)){
                        result ++;
                        used[inext][jnext] = true;
                        deque.push(new int[]{inext, jnext});
                    }
                }
            }
        }
        return;
    }
    
    // 是否满足条件
    public boolean judge(int i, int j, int threshold){
        int now = 0;
        while(i != 0){
            now += i % 10;
            i = i / 10;
        }
        while(j != 0){
            now += j % 10;
            j = j / 10;
        }
        // 不满足
        if(now > threshold){
            return false;
        }else{
            return true;
        }
    }
}

http://www.niftyadmin.cn/n/5445821.html

相关文章

Qt教程 — 3.7 深入了解Qt 控件: Layouts部件

目录 2 如何使用Layouts部件 2.1 QBoxLayout组件-垂直或水平布局 2.2 QGridLayout组件-网格布局 2.3 QFormLayout组件-表单布局 在Qt中&#xff0c;布局管理器&#xff08;Layouts&#xff09;是用来管理窗口中控件位置和大小的重要工具。布局管理器可以确保窗口中的控件在…

微服务高级篇(三):分布式缓存+Redis集群

文章目录 一、单点Redis的问题及解决方案二、Redis持久化2.1 单机安装Redis2.2 RDB持久化2.3 AOF持久化2.4 RDB和AOF对比 三、Redis主从3.1 搭建Redis主从架构3.1.1 集群结构3.1.2 准备实例和配置3.1.3 启动3.1.4 开启主从关系3.1.5 测试 3.2 数据同步3.2.1 全量同步【建立连接…

基于Springboot的西安旅游系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的西安旅游系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

从零开始一步一步掌握大语言模型---(2-什么是Token?)

了解自然语言处理或者听说过大语言模型的同学都听过&#xff0c;token。一般来说&#xff0c;它代表的是语言中不可再分的最小单元。我们人类的语言不仅有文字&#xff0c;还有语音。针对文字、语音来说&#xff0c;它们都各自有不同的划分token的方法。本节将尽可能详细的介绍…

SQL的INTERSECT与MySQL模拟INTERSECT

SQL的INTERSECT 在SQL中&#xff0c;INTERSECT是对两个SQL语句的查询结果做与运算&#xff0c;即值同时存在于两个语句才被选出(交集)。 select id from table1 -- 输出 id(1,2,3) intersect select id from table2 -- 输出 id(2,3,4) //得出 id(2,3)MySQL模拟INTERSECT My…

人像抠图HumanSeg——基于大规模电话会议视频数据集的连接感知人像分割

前言 人像抠图将图像中的人物与背景进行像素级别的区分的技术。通过人像分割&#xff0c;可以实现诸如背景虚化、弹幕穿人等各种有趣的功能&#xff0c;为视频通话和影音观看提供更加优质和丰富的体验。由于广泛部署到Web、手机和边缘设备&#xff0c;肖像分割在兼顾分割精度的…

【3GPP】【核心网】【4G】4G手机接入过程,手机附着过程(超详细)

1. 4G手机接入过程&#xff0c;手机附着过程 附着&#xff08;Attach&#xff09;&#xff1a; 终端在PLMN中注册&#xff0c;从而建立自己的档案&#xff0c;即终端上下文 进行附着的三种情况&#xff1a; ①终端开机后的附着&#xff0c;初始附着 ②终端从覆盖盲区返回到…

Spring Boot 3 极速搭建OAuth2认证框架

本篇环境 Java 17Spring Boot 3.2.3Spring Authorization Server 1.2.3开发工具 SpringToolSuite4Spring Boot 3.2.3 需要JDK 17及之上的版本。 项目初始化 项目可以使用Spring的初始化器生成, 也可以创建一个Maven类型的项目。 项目创建后的目录结构如下: 项目配置 使用 …