[LeetCode](面试题13)机器人的运动范围

题目

地上有一个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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值