写在前面
之前也写过类似的
https://blog.csdn.net/qq_42133142/article/details/111594025
上代码
递归四个方向(与第二十题类似)
class Solution {
public:
int movingCount(int m, int n, int k) {
vector<vector<int>> visit(m, vector<int>(n));
return dfs(visit, 0, 0, m, n, k);
}
int dfs(vector<vector<int>>& visit, int x, int y, int m, int n, int k){
// 先写返回条件
if(x<0 || y<0 || x>=m || y>=n || visit[x][y] || (x/10 + x%10 + y/10 + y%10)>k)
return 0;
cout << "x: " << x << " y: " << y << endl;
// 访问当前---visit,标记
visit[x][y] = 1;
int dx[4] = {-1,1,0,0};
int dy[4] = {0,0,-1,1};
int len = 0;
for(int i=0; i<4; i++){
len += dfs(visit, x+dx[i], y+dy[i],m, n, k);
}
return len+1;
// 与12题相比,不需要取消标记,因为每个点只判断一次。
}
};
优化
只需要递归两个方向,一样可以对所有的坐标点进行判断
即从左上角出发,只要递归的访问右边和下边,所有的坐标都可以访问到
class Solution {
public:
int movingCount(int m, int n, int k) {
vector<vector<int>> visit(m, vector<int>(n));
return dfs(visit, 0, 0, m, n, k);
}
int dfs(vector<vector<int>>& visit, int x, int y, int m, int n, int k){
// 先写返回条件
if(x<0 || y<0 || x>=m || y>=n || visit[x][y] || (x/10 + x%10 + y/10 + y%10)>k)
return 0;
cout << "x: " << x << " y: " << y << endl;
// 访问当前---visit,标记
visit[x][y] = 1;
// 只需要递归 右 和 下 两个方向
int dx[2] = {0,1};
int dy[2] = {1,0};
int len = 0;
for(int i=0; i<2; i++){
len += dfs(visit, x+dx[i], y+dy[i],m, n, k);
}
return len+1;
// 与12题相比,不需要取消标记,因为每个点只判断一次。
}
};
下面的也可也,不过上面的好像更快?
class Solution {
public:
int movingCount(int m, int n, int k) {
vector<vector<int>> visit(m, vector<int>(n));
return dfs(visit, 0, 0, m, n, k);
}
int dfs(vector<vector<int>>& visit, int x, int y, int m, int n, int k){
// 先写返回条件
if(x<0 || y<0 || x>=m || y>=n || visit[x][y] || (x/10 + x%10 + y/10 + y%10)>k)
return 0;
cout << "x: " << x << " y: " << y << endl;
// 访问当前---visit,标记
visit[x][y] = 1;
// 只需要递归 右 和 下 两个方向
int len = 0;
int right = dfs(visit, x+1, y, m, n, k);
int down = dfs(visit, x, y+1, m ,n ,k);
return right+down+1; // +1是加上本身
// 与12题相比,不需要取消标记,因为每个点只判断一次。
}
};