机器人运动问题
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; } }