题目描述
剑指 Offer 13. 机器人的运动范围
难度中等232
地上有一个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
测试用例
- 功能测试(方格为多行多列;k为正数)
- 边界值测试(方格只有一行或者只有一列;k等于0)
- 特殊输入测试(k为负数)
题目考点
- 考察应聘者对回溯法的理解。通常物体或者人在二维方格运行这类问题都可以使用回溯法解决。
- 考察应聘者对数组的编程能力。我们一般都把矩阵看成一个二维数组。只有对数组的特性充分了解,只有可能快速、正确得实现回溯法的代码。
解题思路
和回溯法类似的递归,只是这里不用回滚。
class Solution {
int sums(int x )
{
int s=0;
while(x!=0){
s+=x%10;
x=x/10;
}
return s;
}
int k,m,n;
boolean[][] visited;
public int movingCount(int m,int n,int k){
this.m=m;this.n=n;this.k=k;
this.visited=new boolean[m][n];
return dfs(0,0);
}
private int dfs(int i, int j ){
if(i>=m||j>=n|k<(sums(i)+sums(j))||visited[i][j])
return 0;
visited[i][j]=true;
return 1+dfs(i+1,j)+dfs(i,j+1);
}
}
广度优先搜索方法
import java.util.LinkedList;
/** * Author:Viper * Data:2021/3/11 * description: */
public class problem13 {
int sums(int x )
{
int s=0;
while(x!=0){
s+=x%10;
x=x/10;
}
return s;
}
public int movingCount(int m,int n,int k){
boolean[][] visited=new boolean[m][n];
int res =0;
LinkedList<int[]> queue = new LinkedList<>();
queue.add(new int[]{
0,0});
while(!queue.isEmpty()){
int[] x = queue.poll();
int i=x[0],j=x[1];
if(i>=m||j>=n||k<(sums(i)+sums(j))||visited[i][j])
continue;
visited[i][j]=true;
res++;
queue.add(new int[]{
i+1,j});
queue.add(new int[]{
i,j+1});
}
return res;
}
}