机器人的运动范围(中等)
2020年8月14日
题目来源:力扣
解题
这道题跟昨天的矩阵中的路径类似,只不过这道题更传统,也更简单。初始位置是从左上角开始的,且因为求的是有多种情况的范围而不需要每次都回溯标识。
- DFS
因为不需要回溯标识,所以可以看出机器人每次走的路线都会是右和下。这里我建立了布尔类型的方格数组,用来标识方格是否走过,最后通过遍历求和数组中走过的方格格数,得出机器人的活动范围。
class Solution {
private int[][] dxy={{0,1},{1,0}};
public int movingCount(int m, int n, int k) {
//新建m行n列的方格数组
boolean[][] grid=new boolean[m][n];
int sum=0;
dfs(0,0,k,grid);
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]==true)
sum++;
}
}
return sum;
}
private void dfs(int cur_x,int cur_y,int k,boolean[][] grid){
if(digital(cur_x)+digital(cur_y)>k)
return;
grid[cur_x][cur_y]=true;
for(int i=0;i<2;i++){
int new_x=cur_x+dxy[i][0];
int new_y=cur_y+dxy[i][1];
//防止过界
if(new_x>=0 && new_x<grid.length && new_y>=0 && new_y<grid[0].length&&grid[new_x][new_y]==false){
dfs(new_x,new_y,k,grid);
}
}
}
private int digital(int num){
int res=0;
while(num>0){
res+=num%10;
num/=10;
}
return res;
}
}
- DFS优化
在参考力扣的题解后,发现上个做法可以进行优化
1.每次进入dfs遍历时都会对方格数组长宽进行求值,干脆设置为全局变量
2.dfs不再是void类型,改为int类型,在满足不过界且数位和小于k且没被走过的情况下,返回值加一(表示机器人运动范围+1)再加向右向下两个运动方向的和。
class Solution {
private int m,n;
public int movingCount(int m, int n, int k) {
this.m=m;
this.n=n;
//新建m行n列的方格数组
boolean[][] grid=new boolean[m][n];
int sum=0;
return dfs(0,0,k,grid);
}
private int dfs(int cur_x,int cur_y,int k,boolean[][] grid){
if(cur_x<0 || cur_x>=m || cur_y<0 || cur_y>=n || grid[cur_x][cur_y] ||digital(cur_x)+digital(cur_y)>k)
return 0;
grid[cur_x][cur_y]=true;
return 1+dfs(cur_x,cur_y+1,k,grid)+dfs(cur_x+1,cur_y,k,grid);
}
private int digital(int num){
int res=0;
while(num>0){
res+=num%10;
num/=10;
}
return res;
}
}
- BFS
用队列装载方格点,走过一个方格点后就把它的下边点和右边点加载进队列,一直遍历直到队列为空,输出总和。
class Solution {
public int movingCount(int m, int n, int k) {
int sum=0;
boolean[][] grid=new boolean[m][n];
Queue<int[]> queue=new LinkedList<>();
queue.add(new int[]{0,0});
//判断队列不为空
while(queue.size()>0){
//弹出队首元素
int[] point=queue.poll();
int cur_x=point[0],cur_y=point[1];
if(cur_x<0 || cur_x>=m || cur_y<0 || cur_y>=n || digital(cur_x)+digital(cur_y)>k || grid[cur_x][cur_y])
continue;
grid[cur_x][point[1]]=true;
sum++;
queue.add(new int[]{cur_x,cur_y+1});
queue.add(new int[]{cur_x+1,cur_y});
}
return sum;
}
private int digital(int num){
int res=0;
while(num>0){
res+=num%10;
num/=10;
}
return res;
}
}