地上有一个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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:采用BSF和DFS均可,此处DFS更快一点点。从起点开始,一直向右和向下寻找。BFS同理。
class Solution {
public int res = 0;
public int movingCount(int m, int n, int k) {
//map[i][j]为false代表未统计过
boolean [] [] map = new boolean [m][n];
myCount(map,k,0,0,0,0);
return res;
}
public void myCount(boolean [] [] map,int k,int i,int j,int si,int sj){
map[i][j] = true;
if(si + sj > k){
return;
}
res ++;
/*这里写si-8的意思是,如果i是9,下一个数10的sum为1,即9-8
如果i是19,下一个数20的sum为2 即1+9-8,
如果i是29,下一个数30的sum为3,即2+9-8;
*/
if(i+1 < map.length && !map[i+1][j]){
myCount(map,k,i+1,j,(i + 1) % 10 != 0? (si + 1) : (si-8) ,sj);
}
if(j+1 < map[0].length && !map[i][j + 1]){
myCount(map,k,i,j + 1,si ,(j + 1) % 10 != 0? (sj + 1) : (sj - 8));
}
}
}
/*此处可以不用getSum()方法,由于BFS写的少,逻辑不够清晰,所以用那个方法来减少参数的传递,避免混乱*/
class Solution {
public int res = 0;
public int movingCount(int m, int n, int k) {
boolean [] [] map = new boolean [m][n];
Queue<int[]> que= new LinkedList<int[]>();
que.add(new int []{0,0});
map[0][0] = true;
bfs(m,n,k,que,map);
return res;
}
public void bfs(int m,int n,int k,Queue<int []>que,boolean[][] map){
int [] xy;
while((xy = que.poll()) != null){
int x= xy[0];
int y = xy[1];
System.out.println("x:"+x+",y:"+y);
res++;
if(x + 1< m && getSum(x+1,y) <= k && !map[x+1][y]){
map[x + 1][y] = true;
que.offer(new int []{x+1,y});
}
if(y + 1< n && getSum(x,y+1) <= k && !map[x][y+1]){
map[x][y + 1] = true;
que.offer(new int []{x,y+1});
}
}
}
public static int getSum(int num1,int num2){
int sum = 0;
while(num1 / 10 != 0){
sum += num1 % 10;
num1 /= 10;
}
sum += num1;
while(num2 / 10 != 0){
sum += num2 % 10;
num2 /= 10;
}
sum += num2;
return sum;
}
}