深度优先搜索DFS或广度优先搜索BFS:力扣剑指 Offer 13. 机器人的运动范围

1、题目描述:

在这里插入图片描述

2、题解:

数位之和计算:

def sums(x):
    s = 0
    while x != 0:
        s += x % 10
        x = x // 10
    return s

此题数据范围[1,100],而且x只能x+1或者x-1
(x + 1) % 10 =0 时,s(x+1) = s(x) - 8,如19,20的数位之和分别是10,2;
(x + 1) % 10 !=0 时,s(x+1) = s(x) + 1,如2,3的数位之和分别是2,3;
代码如下:

s_x + 1 if (x + 1) % 10 else s_x - 8

搜索方向简化:
机器人仅通过向下或者向右,可以访问所有点
方法1:广度优先搜索BFS
通常利用队列实现广度优先遍历。像水的波纹:一圈一圈向外扩散

初始化: 将机器人初始点 (0,0)加入队列 queue ;
迭代终止条件: queue 为空。代表已遍历完所有可达解。
迭代工作:
	单元格出队: 将队首单元格的索引弹出,作为当前搜索单元格。
	判断是否跳过: 若 ① 行、列索引越界 或 ② 数位和超出目标值 k  或 ③ 当前元素已访问过  时,执行 continue 。
	标记当前单元格 :将单元格索引 (i, j) 存入 visited 中,代表此单元格 已被访问过 。
	单元格入队: 将当前元素的 下方、右方 单元格的 索引加入 queue  。
返回值: visited 的长度 len(visited) ,即可达解的数量。

代码如下:

class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        #BFS
        #计算数位之和
        def digitsum(x):
            s = 0
            while x != 0:
                s += x % 10
                x = x // 10
            return s
        queue,visited = [(0,0)],set()
        while queue:
            i,j = queue.pop(0)
            if i >= m or j >= n or digitsum(i) + digitsum(j) > k  or (i,j) in visited:
                continue
            visited.add((i,j))
            queue.append((i+1,j))
            queue.append((i,j+1))
        return len(visited)

方法2:深度优先搜索DFS
可以理解为暴力法模拟机器人在矩阵中的所有路径。DFS通过递归,先朝一个方向搜到底,再回溯至上个节点,沿另一个方向搜索,以此类推。
剪枝: 在搜索中,遇到数位和超出目标值、此元素已访问,则应立即返回,称之为可行性剪枝

终止条件:若 ① 行、列索引越界 或 ② 数位和超出目标值 k  或 ③ 当前元素已访问过 时 返回0
递推工作:
    1)标记当前单元格:将索引(i,j)存入visited中,代表此单元格已被访问
    2)搜索下一个单元格:计算当前元素的下,右两个方向元素的数位和,并开启下层递归
回溯返回值:返回1 + 右方搜索的可达解数量 + 下方搜索的可达解总数,代表从本单元格递归搜索的可达解总数

代码如下:

class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        #DFS
        # 计算数位之和
        def digitsum(x):
            s = 0
            while x != 0:
                s += x % 10
                x = x // 10
            return s
        def dfs(i,j):
            if i >= m or j >= n or digitsum(i) + digitsum(j) > k or (i,j) in  visited:
                return 0
            visited.add((i,j))
            return 1 + dfs(i + 1,j) + dfs(i,j + 1)
        visited = set()
        return dfs(0,0)

3、复杂度分析:

时间复杂度都是O(MN),M,N分别是行和列的长度
空间复杂度都是O(MN)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值