力扣,这个力扣描述题目不清晰,参考《剑指offer》书
本题与66题区别在于不用回溯!即不用把走过的地方还原回来!!!每到1个点会有4个不同的机器人分别去探路,相互之间不会走重复的网点。
题目描述:
地上有一个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。请问该机器人能够到达多少个格子?
Python
class Solution:
def wardrobeFinishing(self, m: int, n: int, cnt: int) -> int:
grid = [[0] * n for _ in range(m)]
visited = [[0] * n for _ in range(m)] # 不能直接grid.copy(), 浅层复制
for i in range(m):
for j in range(n):
grid[i][j] = self.digit(i) + self.digit(j)
res = self.dfs(grid, 0, 0, m, n, cnt, visited)
return res
def dfs(self, grid, i, j, m, n, cnt, visited):
if i < 0 or i >= m or j < 0 or j >= n or grid[i][j] > cnt or visited[i][j]:
return 0
visited[i][j] = 1
# 不用回溯的原因是每个格子只用走1遍即可, 没有再次走的可能
return (1 + self.dfs(grid, i-1, j, m, n, cnt, visited)
+ self.dfs(grid, i+1, j, m, n, cnt, visited)
+ self.dfs(grid, i, j-1, m, n, cnt, visited)
+ self.dfs(grid, i, j+1, m, n, cnt, visited))
def digit(self, x):
res = 0
while x > 0:
res += x % 10
x = x // 10
return res
Java
class Solution {
public int wardrobeFinishing(int m, int n, int cnt) {
int[][] used = new int[m][n];
return dfs(m, n, cnt, 0, 0, used);
}
public int dfs(int m, int n, int cnt, int i, int j, int[][] used) {
int count = 0;
if (i < 0 || i >= m
|| j < 0 || j >= n
|| used[i][j] == 1
|| digit(i) + digit(j) > cnt) {
return 0;
}
used[i][j] = 1;
count = 1 + dfs(m, n, cnt, i - 1, j, used)
+ dfs(m, n, cnt, i + 1, j, used)
+ dfs(m, n, cnt, i, j - 1, used)
+ dfs(m, n, cnt, i, j + 1, used);
return count;
}
public int digit(int x) {
int res = 0;
while (x > 0) {
res += x % 10;
x /= 10;
}
return res;
}
}
##Solution1:
此题和66题均是典型的回溯法题目,对比记忆思路!
class Solution {
public:
int movingCount(int threshold, int rows, int cols) {
bool *visited = new bool[rows * cols];
memset(visited, 0, rows * cols);
int count = movingCountCore(threshold, rows, cols, 0, 0, visited);
delete []visited;
return count;
}
int movingCountCore(int threshold, int rows, int cols, int row, int col, bool *visited) {
int count = 0;
if(row >= 0 && row < rows && col >= 0 && col <cols
&& getDigitSum(row) + getDigitSum(col) <= threshold
&& !visited[row * cols + col]) {
visited[row * cols + col] = true;
count = 1 + movingCountCore(threshold, rows, cols, row - 1, col, visited)
+ movingCountCore(threshold, rows, cols, row + 1, col, visited)
+ movingCountCore(threshold, rows, cols, row, col - 1, visited)
+ movingCountCore(threshold, rows, cols, row, col + 1, visited);
}
return count;
}
int getDigitSum(int n) {
int result = 0;
while(n != 0) {
result += n%10;
n /= 10;
}
return result;
}
};