一、题目
地上有一个 m 行和 n 列的方格。一个机器人从坐标 (0,0) 的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当 k 为 18 时,机器人能够进入方格(35,37),因为 3+5+3+7 = 18。但是,它不能进入方格(35,38),因为 3+5+3+8 = 19。请问该机器人能够达到多少个格子?
二、思路
回溯法:
- 创建一个 m * n 的数组,表示 m 行和 n 列的方格,用以记录机器人走过的格子。走过的格子置 1,没走过的格子置 0;
- 从 (0, 0) 开始走,成功走一步则将当前的格子置 1,然后向左、右、上、下四个方向探索,返回 1 + 四个方向探索值,即为当前位置机器人走过的格子;
- 向四个方向探索时,行和列都不能出格,且当前位置没有走过,还要保证当前坐标的数位之和小于给定的 k。
三、代码
class Solution {
public int movingCount(int m, int n, int k) {
// 标志矩阵,0 表示没走过的格子,1 表示走过的格子
int[][] flag = new int[m][n];
return backTrack(0, 0, m, n, k, flag);
}
/*
(i, j):当前的位置
m:行数
n:列数
k:阈值
flag:标志矩阵
*/
public int backTrack(int i, int j, int m, int n, int k, int[][] flag){
/*
边界条件:
(1)(i, j)不能越界;
(2)(i, j)格子没走过;
(3)(i, j)的数位和不能大于 k。
*/
if(i < 0 || i >= m || j < 0 || j >= n || flag[i][j] == 1 || getBitSum(i) + getBitSum(j) > k)
return 0;
flag[i][j] = 1;
return 1 +
backTrack(i - 1, j, m, n, k, flag) +
backTrack(i + 1, j, m, n, k, flag) +
backTrack(i, j - 1, m, n, k, flag) +
backTrack(i, j + 1, m, n, k, flag);
}
// 求一个数的数位和
public int getBitSum(int num){
int sum = 0;
while(num != 0){
sum += (num % 10);
num = num / 10;
}
return sum;
}
}