题目
地上有一个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
思路
dfs递归思想
虽然说每个点可以往四个方向走,但是考虑到是从[0,0]走到右下的某目标点,所以只需要考虑向右和向下的方向就可以了。对于递归过程中的一些参数,设置了全局变量。
- 时间复杂度O(MN)
- 空间复杂度O(MN)
class Solution {
public:
int movingCount(int m, int n, int k) {
//初始化
nrows = m;
ncols = n;
limit = k;
for(int i=0; i<m; i++){
for(int j=0; j<n; j++){
flag[i][j] = 0;
}
}
return dfs(0,0);
}
private:
int nrows, ncols, limit;
int flag[100][100];
int dfs(int x, int y){
//终止条件
if( x >=nrows || y>= ncols || flag[x][y]==1 || (computeSum(x)+computeSum(y)>limit) ){
return 0;
}
//每个结点可以选择向右或者向下走
flag[x][y] = 1;
return 1 + dfs(x+1,y) + dfs(x,y+1);
}
int computeSum(int a){
int sum = 0;
while( a>0 ){
sum += a%10;
a = a/10;
}
return sum;
}
};
bfs
每次取出队列的所有结点,然后每个结点可以选择向右或右下试探,如果没问题就加入队列。如此循环直到队列为空。
- 时间复杂度O(MN)
- 空间复杂度O(MN)
class Solution {
public:
int movingCount(int m, int n, int k) {
queue<pair<int,int> > que;
int flag[m][n];
for(int i=0; i<m; i++){
for(int j=0; j<n; j++){
flag[i][j] = 0;
}
}
//出发点
que.push({0,0});
flag[0][0] = 1;
int anws = 1;
while( !que.empty() ){
//取出队列所有点,每个点都往右往下试探
int size = que.size();
for(int i=0; i<size; i++){
pair<int,int> node = que.front();
que.pop();
int x = node.first;
int y = node.second;
//往两个方向试探
for(int j=0; j<2; j++){
int newx = x + dirs[j][0];
int newy = y + dirs[j][1];
if( newx<m && newy<n && flag[newx][newy]!=1 && (computeSum(newx)+computeSum(newy))<=k ){
que.push({newx,newy});
flag[newx][newy] = 1;
anws++;
}
}
}
}
return anws;
}
private:
int dirs[2][2] = {{1,0},{0,1}};
int computeSum(int a){
int sum = 0;
while( a>0 ){
sum += a%10;
a = a/10;
}
return sum;
}
};