题目描述:
思路总结:
思路:采用递归的思想
对于一个格子,如果满足要求(它的行坐标和列坐标的数位之和不大于k,同时坐标点的坐标要满足0≤i≤m, 0≤j≤n),那么就将该坐标格子的visited设置为visited[i][j]=true, 并依次递归访问其右、左、下、上的格子,如果其中(右、左、下、上)也满足条件,就递归,分别计算各自递归下的满足条件的格子数,最终基于坐标(i, j)的格子计算出的满足条件的格子=上递归结果+下递归结果+左递归结果+右递归结果+1(这个1是格子本身)
递归结束条件(返回值为0)是:上下左右都已经访问过或者不满足条件(它的行坐标和列坐标的数位之和大于k,或者坐标点的坐标不满足0≤i≤m, 0≤j≤n)
注意:
这里的visited必须添加&,保证深层递归对结果的影响能够被递归入口处的visited同步到,不然递归结束之后,入口处使用的visited还是原来的visited。就会导致错误。
代码如下:
class Solution {
private:
public:
//思路:采用递归的思想
/*
对于一个格子,如果满足要求,那么就依次访问其上、下、左、右的格子,如果其中满足条件,就递归。
递归结束条件是:上下左右都已经访问过或者不满足条件
*/
//这里的visited必须添加&,保证深层递归对结果的影响能够被递归入口处的visited同步到,不然递归结束之后,入口处使用的visited还是原来的visited。就会导致错误。
int check(vector<vector<int>> &visited, int vertical, int horizontal, int k, int m, int n){
// 定义四个方向
vector<pair<int, int>> directions{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
//判断vertical与horizontal的数位之和是否满足条件
if(vertical<0||vertical>=m||horizontal<0||horizontal>=n){ // 如果不满足条件
return 0;
}else{
//判断数位是否满足条件
int result = 0;
int temp_cal = vertical;
int temp = vertical;
while(temp!=0){
temp_cal = temp%10;
result += temp_cal;
temp = temp/10;
}
temp_cal = horizontal;
temp = horizontal;
while(temp!=0){
temp_cal = temp%10;
result += temp_cal;
temp = temp/10;
}
if(result>k){
return 0;
}
}
// int total =0;
// 如果这个点访问过
if(visited[vertical][horizontal]){
return 0;
}
else{
visited[vertical][horizontal] = true;
}
int total = 0;
for(const auto&dir:directions){
total += check(visited, vertical+dir.first, horizontal+dir.second, k, m, n);
cout<<total<<endl;
}
return total+1;
}
int movingCount(int m, int n, int k) {
// 初始化一个矩阵保存一个格子是否访问过
vector<vector<int>> visited(m, vector<int>(n));
// int number=0;
//调用check返回总共可以到达多少个格子
int number = check(visited, 0, 0, k, m, n);
return number;
}
};
经过运行,该算法最终的空间和时间复杂度都比较高,于是又参考了评论区别人的思路。