难度:中等
地上有一个 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
。请问该机器人能够到达多少个格子?
输入:m = 2, n = 3, k = 1
输出:3
输入:m = 3, n = 1, k = 0
输出:1
提示:
1 <= n,m <= 100
0 <= k <= 20
我们将行坐标和列坐标数位之和大于 k
的格子看作障碍物,那么这道题就是一道很传统的搜索题目,我们可以使用广度优先搜索或者深度优先搜索来解决它,本文选择使用 广度优先搜索 的方法来讲解。
那么如何计算一个数的数位之和呢?
x
每次对 10 取余,就能知道数 x
的个位数是多少,然后再将 x
除 10,这个操作等价于将 x 的十进制数向右移一位,删除个位数(类似于二进制中的 >>
右移运算符),不断重复直到 x
为 0 时结束。C++
class Solution {
private:
int getsum(int x){
int ans = 0;
while(x > 0 ){
ans += x % 10;
x /= 10;
}
return ans;
}
public:
int movingCount(int m, int n, int k) {
if(k == 0) return 1;
vector<pair<int, int>> dirs{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
queue<pair<int, int>> q;
q.push(make_pair(0, 0));
vector<vector<int>> visited(m, vector<int>(n));
visited[0][0] = 1;
int ans = 1;
while(!q.empty()){
auto [x, y] = q.front();
q.pop();
for(auto dir : dirs){
int cur_x = x + dir.first, cur_y = y + dir.second;
if(cur_x < 0 || cur_x >= m || cur_y < 0 || cur_y >= n || visited[cur_x][cur_y] || getsum(cur_x) + getsum(cur_y) > k) continue;
q.push(make_pair(cur_x, cur_y));
visited[cur_x][cur_y] = 1;
ans++;
}
}
return ans;
}
};
Java
class Solution {
private int getsum(int x){
int ans = 0;
while(x > 0 ){
ans += x % 10;
x /= 10;
}
return ans;
}
public int movingCount(int m, int n, int k) {
if(k == 0) return 1;
int[][] dirs = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
Queue<int[]> q = new LinkedList<int[]>();
q.offer(new int[]{0, 0});
int[][] visited = new int[m][n];
visited[0][0] = 1;
int ans = 1;
while(!q.isEmpty()){
int[] cell = q.poll();
for(int[] dir : dirs){
int cur_x = cell[0] + dir[0], cur_y = cell[1] + dir[1];
if(cur_x < 0 || cur_x >= m || cur_y < 0 || cur_y >= n || visited[cur_x][cur_y] == 1 || getsum(cur_x) + getsum(cur_y) > k) continue;
q.offer(new int[]{cur_x, cur_y});
visited[cur_x][cur_y] = 1;
ans++;
}
}
return ans;
}
}
m
为方格的行数,n
为方格的列数。考虑所有格子都能进入,那么搜索的时候一个格子最多会被访问的次数为常数,所以时间复杂度为 O ( 4 m n ) = O ( m n ) O(4mn) = O(mn) O(4mn)=O(mn)。题目来源:力扣。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!