LeetcodeMedium-【面试题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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

目录

思路1:深搜(dfs)

思路2:广搜(bfs)

思路3:递推


思路1:深搜(dfs)

从起点(0,0)开始朝四个方向搜索,能够继续的条件就是坐标的位数和不大于K.

传统的深搜是四个方向的,但是本题可以优化为:向右和向下。

class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        # 暴力
        self.cnt = 0
        self.n = n
        self.m = m
        self.k = k
        self.visit = [[0]*n for _ in range(m)]
        self.dx = [0, 1] # 优化为只:向右、向下
        self.dy = [1, 0]
        
        self.visit[0][0] = 1
        self.dfs(0, 0)

        return self.cnt
    
    def dfs(self, x, y):
        ti = x
        tj = y
        t = 0
        while ti > 0:
            t += ti % 10
            ti = ti // 10
        while tj > 0:
            t += tj % 10
            tj = tj // 10
        if t <= self.k:
            self.cnt += 1
        else:
            return 
        for i in range(2):
            xx = x + self.dx[i]
            yy = y + self.dy[i]
            if 0 <= xx < self.m and 0 <= yy < self.n and self.visit[xx][yy] == 0:
                self.visit[xx][yy] = 1
                self.dfs(xx, yy)
        

思路2:广搜(bfs)

广搜是利用一个队列实现的,且本题利用set进行去重。

def digitsum(n):
    ans = 0
    while n:
        ans += n % 10
        n //= 10
    return ans

class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        from queue import Queue
        q = Queue()
        q.put((0, 0))
        s = set()
        while not q.empty():
            x, y = q.get()
            if (x, y) not in s and 0 <= x < m and 0 <= y < n and digitsum(x) + digitsum(y) <= k:
                s.add((x, y))
                q.put((x, y + 1))
                q.put((x + 1, y))
        return len(s)

    

思路3:递推

def digitsum(n):
    ans = 0
    while n:
        ans += n % 10
        n //= 10
    return ans

class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        s = set([(0, 0)])
        for i in range(m):
            for j in range(n):
                if ((i-1,j) in s or (i,j-1) in s) and digitsum(i) + digitsum(j) <= k:
                    s.add((i, j))
        return len(s)
发布了314 篇原创文章 · 获赞 22 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_39451578/article/details/105427334
今日推荐