【剑指 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

解题思路

简单递归,题目规定从坐标【0,0】出发,可以上下左右的移动一格,但是必须保证横坐标和纵坐标的树位之和不能大于k。

举例说明 流程如下:
输入:m = 2, n = 3, k = 1
2行3列的二维数组 * 代表格子 o代表机器人走过的格子

【
      *,*,*
      *,*,*
】

当前机器人所在的位置:【0,0】

【
      o,*,*
      *,*,*
】

数位和 0+0<1 满足条件 可以进行下一次移动(上下左右任意方向)
向左向上肯定不行 因为超出边界 只能向右或者向下
先向右移动一格

【
      o,o,*
      *,*,*
】

当前机器人所在位置【0,1】
数位和 0+1<=1 满足条件 可以进行下一次移动(上下左右任意方向)

向右移动一格(此步是说明不满足条件)

【
      o,o,o
      *,*,*
】

当前机器人所在位置【0,2】
数位和 0+2>1 不满足条件 所以此步无效, (递归回退)只能由【0,1】的位置向下运动
因为【0,0】走过,【0,2】不满足条件
(此步是说明不满足条件)

【
      o,o,*
      *,o,*
】

当前机器人所在位置【1,1】
数位和 1+1>1 不满足条件 所以此步无效 , (递归回退)只能由【0,0】的位置向下运动
因为【0,2】不满足条件 【1,1】不满足条件

【
      o,o,*
      o,*,*
】

当前机器人所在位置【1,0】
在进行上下左右都不满足所以停止。
满足条件的格子共有3个


实现:
定义一个visited数组记录当前位置是否走过。
定义一个二维数组matrix记录所有的格子
i,j表示当前的位置坐标
sums方法求数位和

递归终止条件:当超出边界或者该格子访问过或者数位和不满足条件时。

需要注意的是:格子可以多次走过,但是走过了的就不能在算新格子加1,所以我这么设计

代码

class Solution {
    private int sum = 0;

    public int movingCount(int m, int n, int k) {
        int[][] matrix = new int[m][n];
        int[][] visited = new int[matrix.length][matrix[0].length];
        moving(matrix, visited, 0, 0, k);
        return sum;

    }

    public void moving(int[][] matrix, int[][] visited, int i, int j, int k) {
		//当超出边界或者该格子访问过或者数位和不满足条件时。 递归终止
        if (i < 0 || j < 0 || i >= matrix.length || j >= matrix[0].length || visited[i][j] == 1 || sums(i) + sums(j) > k) {
            return;
        }
        //满足所有条件 机器人能到达的格子数加1
        if (visited[i][j] == 0 && sums(i) + sums(j) <= k) {
            sum += 1;
        }
        visited[i][j] = 1;//记录标记
        moving(matrix, visited, i, j - 1, k);//左
        moving(matrix, visited, i, j + 1, k);//右
        moving(matrix, visited, i - 1, j, k);//上
        moving(matrix, visited, i + 1, j, k);//下
    }
    
    /**
     *  求数位和
     * @param x
     * @return
     */
    private int sums(int x) {
        int s = 0;
        while (x != 0) {
            s += x % 10;
            x = x / 10;
        }
        return s;
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_35416214/article/details/107442606