题目
地上有一个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。请问该机器人能够到达多少个格子?
示例 1:
输入:m = 2, n = 3, k = 1
输出:3
示例 2:
输入:m = 3, n = 1, k = 0
输出:1
提示:
1 <= n,m <= 100
0 <= k <= 20
解题思路
讲几个注意点:
1、如何计算一个数的数位之和?只需要对数 num 每次对 10 取余,就能知道数 num 的个位数是多少,然后再将 num 除 10,这个操作等价于将 num 的十进制数向右移一位,删除个位数(类似于二进制中的 >> 右移运算符),不断重复直到 num 为 0 时结束。
2、缩小搜索方向,本题不必向四个方向都进行搜索,其实只用向下或者向右就可以了。
3、在BFS或者DFS的过程中,需要把已经访问过的点加入到已访问集合中,避免重复访问。
4、其他要注意的就是不要越界,以及数位之和不大于k。
代码
解法一:广度优先搜索
# BFS
class Solution:
def digitsum(self, num):
ans = 0
while num:
ans += num % 10 # 每次计算个位
num //=10
return ans
def movingCount(self, m: int, n: int, k: int) -> int:
directions = [(1, 0), (0, 1)] # 隐藏条件,可以只向右或向下遍历
res = 1
visited = {(0, 0)}
queue = [(0, 0)]
while queue:
x, y = queue.pop(0)
for dx, dy in directions:
if 0<=x+dx<m and 0<=y+dy<n and self.digitsum(x+dx) + self.digitsum(y+dy)<=k and (x+dx, y+dy) not in visited:
res += 1
visited.add((x+dx, y+dy))
queue.append((x+dx, y+dy))
return res
解法二:深度优先搜索
# DFS
class Solution:
def digitsum(self, num):
ans = 0
while num:
ans += num % 10 # 每次计算个位
num //=10
return ans
def movingCount(self, m: int, n: int, k: int) -> int:
visited = set()
def dfs(x, y):
if x>=m or y>=n or self.digitsum(x)+self.digitsum(y)>k or (x, y) in visited:
return 0
count = 1
visited.add((x, y))
count += dfs(x+1, y) # 只向下或者向右遍历
count += dfs(x, y+1)
return count
res = dfs(0, 0)
return res