题目:
地上有一个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。请问该机器人能够到达多少个格子?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解:
解法一:DFS(暴力法)
class Solution {
int m, n, k;
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, 0, 0);
}
int sum(int a){
int y = a/10;
int z = a%10;
return y+z;
}
int dfs(int i, int j, int sumi, int sumj){
if(i>=m || j>=n || sumi+sumj>k || visited[i][j]){
return 0;
}
visited[i][j] = true;
return 1 + dfs(i+1, j, sum(i+1), sum(j)) + dfs(i, j+1, sum(i), sum(j+1));
}
}
笔记:
(1)根据题设标出矩阵中位数和小于k的元素,发现都是上三角形式,通过向右向下移动可达,因此如果向下向右不可达,就真的不可达了。
(2)出错:
1)因为dfs函数里使用了m,n,k等,所以在movingCount函数外面设变量
2)sum求位数和函数,m和n小于等于一百,因此只有两位和一位数,之前以为包含100所以写的很麻烦
3)dfs函数中return第三部分j忘记+1了
解法二:BFS
class Solution {
public int movingCount(int m, int n, int k) {
Queue<int[]> queue = new LinkedList<int[]>();
boolean[][] visited = new boolean[m][n];
int res = 0;
queue.add(new int[] {0,0});
while(queue.size()>0){
int[] x = queue.poll();
int i = x[0], j = x[1];
int sumi = sum(i), sumj = sum(j);
if(i>=m || j>=n || sumi+sumj>k || 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;
}
int sum(int a){
int y = a/10;
int z = a%10;
return y+z;
}
}
笔记:
(1)广度优先遍历,使用queue队列存放待访问元素,使用visited矩阵存放已访问的元素
(2)速度慢可能是因为每次都要调用两次sum函数,k神的那个求位数的方法很巧妙但是我一时半会看不明白啊,唉……
(3)出错:
1)Queue<int[]> queue一开始忘记在int后面加[],在写到后面的时候发现我每次存进去的是一个{x,y}类型而不是一个整型;new LinkedList<int[]>()最后的()忘记写了
2)queue的方法:压入是add()不是push(),弹出式poll()不是pop()
3)每次压入时应为 new int[] {i, j},前面的new int[]不能少
4)判断越界的时候是大于等于m