剑指offer 13. 机器人的运动范围
题目描述
解题思路
注意和剑指 Offer 12. 矩阵中的路径的区别。
此题方格中的每个元素在整个过程中仅能访问一次,所以只要访问过某一个元素, visited 就标记为true。
所以此题仅仅只是普通的DFS遍历,配合 visited 数组标记已访问,并不是回溯。
class Solution {
public int movingCount(int m, int n, int k) {
boolean[][] visited = new boolean[m][n];
return dfs(m, n, 0, 0, k, visited);
}
//计算从[row, col]开始,能够到达多少格子
int dfs(int m, int n, int row, int col, int k, boolean[][] visited) {
//base case:如果越界,或者行列数位之和大于k,或者已经访问过,则直接返回
if (row < 0 || row >= m || col < 0 || col >= n || !isValid(row, col, k) || visited[row][col])
return 0;
//只要访问过,就标记为true
visited[row][col] = true;
//四个方向
return 1 + dfs(m, n, row + 1, col, k, visited)
+ dfs(m, n, row - 1, col, k, visited)
+ dfs(m, n, row, col + 1, k, visited)
+ dfs(m, n, row, col - 1, k, visited);
}
//判断当前位置的行列数位之和是否大于k,如果大于k,则说明非法,返回false
boolean isValid(int row, int col, int k) {
if (getDigitSum(row) + getDigitSum(col) > k)
return false;
return true;
}
//计算一个数字的数位之和
int getDigitSum(int number) {
int sum = 0;
while (number > 0) {
sum += number % 10;
number /= 10;
}
return sum;
}
}