题目
地上有一个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。请问该机器人能够到达多少个格子?
示例 :
输入:m = 2, n = 3, k = 1
输出:3
思路
本题与 矩阵中的路径 题目有相似之处,是典型的搜索问题,可以用递归实现的深度优先解决。
递归需要用到状态或者子问题的概念。
方格可看成m*n的矩阵。假设当前坐标为(i,j),那么问题转化为从(i,j)出发,机器人最多能到达多少个格子。
构造子问题:
根据机器人的运动规则,机器人从(i,j)出发,能够到达(i+1,j),(i-1,j),(i,j+1),(i,j-1)四个位置。子问题是,机器人从上面这四个方向出发,分别能到达多少个格子。如果求出子问题的解,然后将它们全部整合起来再加1就得到了原问题的解。加1的原因是包含当前(i,j)这个格子。
对于矩阵搜索,需要定义一个二维矩阵来记录当前格子是否被访问过,一旦访问过,说明该格子已经包含在子问题中,需要返回0,避免重复计算。
深度优先搜索的返回条件:
1、下标越界
2、已经访问过该格子
3、该格子行坐标和列坐标的数位之和大于k
代码
class Solution:
def movingCount(self, m: int, n: int, k: int) -> int:
visit = [[False for _ in range(n)] for _ in range(m)]
res = self.dfs(0,0,m,n,k,visit)
return res
def sum_digit(self,digit):
s = 0
while digit:
s += digit % 10
digit //=10
return s
def dfs(self,i,j,m,n,k,visit):
if i<0 or j<0 or i>=m or j>=n:
return 0
if self.sum_digit(i)+self.sum_digit(j)>k:
return 0
if visit[i][j]==1:
return 0
visit[i][j]=True
return 1+self.dfs(i-1,j,m,n,k,visit)+self.dfs(i+1,j,m,n,k,visit)+self.dfs(i,j-1,m,n,k,visit)+self.dfs(i,j+1,m,n,k,visit)
复杂度
时间复杂度:O(mn)
空间复杂度:O(mn)
知识点
在python中,
" / " 表示浮点数除法,返回浮点结果;
" // " 表示整数除法,返回不大于结果的一个最大的整数。