和面试题12的解题思路几乎一致,利用dfs+回溯,不过这次题目的意思是,要计算所有能够到达的小格子的个数,而不是最长路径数,所以没必要比大小,直接自增就可以了。
class Solution {
private:
vector<vector<int>> dir = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int maxLen;
bool vis[300][300] = {false};
public:
// 计算每一位之和
int cal(int num1, int num2){
int res = 0;
while(num1 > 0){
res += (num1 % 10);
num1 /= 10;
}
while(num2 > 0){
res += (num2 % 10);
num2 /= 10;
}
return res;
}
void helper(int m, int n, int k, int c_x, int c_y, int index){
int i;
// 在四个方向上去搜索
// 其实看过题解之后发现,
// 不用在四个方向上去找,只找两个方向,既:下和右就行
vis[c_x][c_y] = true;
for(auto xy : dir){
int x = c_x + xy[0], y = c_y + xy[1];
if(x >= m || x < 0 || y >= n || y < 0 || vis[x][y] || cal(x, y) > k) continue;
else{
// 直接递增就可以,原来以为要找最长路径
// 后来发现题目的意思是,找最大能到达的格子数,
// 也就是连通分量的结点数
maxLen ++;
helper(m, n, k, x, y, index + 1);
}
}
}
int movingCount(int m, int n, int k) {
if(m <= 0 || n <= 0) return 0;
if(k == 0) return 1;
maxLen = 1;
helper(m, n, k, 0, 0, 1);
return maxLen;
}
};