机器人运动问题

1:问题描述

地上有一个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
示例 1:

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2:问题分析

这是典型的二维数组搜索问题,采用深度搜索的算法(递归算法),明确以下处理方法。

首先在二维数组上判断哪些位置数据满足要求,将满足要求的标记为1,不满足要求的标记为0,然后再使用递归的算法,以(0,0)为起点,向上下左右进行递归判断,满足要求则统计及个数即可。最重要的地方是明确递归的三要素

  • 终止条件:当坐标不超过边界,或者当前位置数据为0,或者当前数据为2(即已经标记过了),的情况下返回false,退出递归。
  • 终止条件下的处理:不做处理,直接返回false。
  • 重复步骤:首先判断当前位置数据是否满足要求,若满足,则判断是不是为1,如果为1,先将计数器加一,然后向其上下左右继续递归即可。这里要注意的是向上下左右继续判断的之间不是if else的关系,而是if和if的关系,即无论上次判断的方向结果怎么样,都要再向其他方向再判断!

3:看看代码

//先遍历二维数组,将行列数位之和小于等于k的坐标标记为1!
//按照以(0,0)为起点,将所有相近的点连接起来!即可。
class Solution {
    int[][] arr ;
    int numbers= 0;
    public int movingCount(int m, int n, int k) {
        //遍历二维数组,将满足条件的标记为1
        arr = new int[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if((i%10+i/10+j%10+j/10)<=k){
                    arr[i][j] = 1;
                }
            }
        }
//        //打印二维数组
//        for(int[] a:arr) {
//            System.out.println(Arrays.toString(a));
//        }
        //从(0,0)位置,开始将能连成片的1,进行统计
        statstic(0,0,m,n);
        return numbers;
    }

    //从坐标(i,j)开始,统计相连的为1的点的个数
    public boolean statstic(int i,int j,int m, int n) {
        //打印二维数组
//        System.out.println("当前二维数组");
//        for(int[] a:arr) {
//            System.out.println(Arrays.toString(a));
//        }
        //终止条件,如果超过边界,或者当前位置为0,则终止本次递归
        //因为标记为2,意味着已经统计过了,所以遇到为2的也直接退出。
        if(i<0||i>=m||j<0||j>=n||arr[i][j]==0||arr[i][j]==2){
            return false;
        }
        //如果当前位置为1,则意味着该位置满足递归条件,要进行向上下左右的递归
        if(arr[i][j]==1){
            //计数器加一!
            numbers++;
            //将该位置标记为2,意味着已经统计过了
            arr[i][j] = 2;
            //往上方判断
            if(statstic(i-1,j,m,n)){
                return true;
            }
            //往下方判断
            if(statstic(i+1,j,m,n)){
                return true;
            }
            //往右方判断
            if(statstic(i,j+1,m,n)){
                return true;
            }
            //往左方判断
            if(statstic(i,j-1,m,n)){
                return true;
            }
        }
        return false;
    }
}