面试题13:机器人的运动范围

题目:地上有一个m行n列的方格。一个机器人从坐标(0,0)的格子开
始移动,它每次可以向左、右、上、下移动一格,但不能进入行坐标和列
坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格
(35, 37),因为3+5+3+7-18。但它不能进入方格(35, 38),因为3+5+3+8-19。请问该机器人能够到达多少个格子?

和前面的题目类似,这个方格也可以看作-一个
mXn的矩阵。同样,在
这个矩阵中,除边界上的格子之外,其他格子都有4个相邻的格子。
机器人从坐标(0,0)开始移动。当它准备进入坐标为(i, j)的格子时,通过
检查坐标的数位和来判断机器人是否能够进入。如果机器人能够进入坐标
为(i,j)的格子,则再判断它能否进入4个相邻的格子(i,j-1)、(i-1,j)、(i,j+1)
和(i+1,j)。因此,我们可以用如下的代码来实现回溯算法:

# 面试题13 机器人的运动范围
'''
判断位数之和有两种方法:
    1.转化为字符串
    2.通过循环,例如a=101,每次对a进行%10,循环判断条件是a!=0
    https://www.cnblogs.com/54Leo/p/6133270.html
    https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E6%9C%BA%E5%99%A8%E4%BA%BA%E7%9A%84%E8%BF%90%E5%8A%A8%E8%8C%83%E5%9B%B4.py
和面试题12一样使用回溯法,进行迭代,套路很相近

另外,用visited = [[False] * rows ]* cols这种方式创建二维数组,是个坑,虽然行,但都是array的引用。
应该用test = [[0 for i in range(m)] for j in range(n)]这种方式。
https://www.cnblogs.com/PyLearn/archive/2017/11/06/7795552.html

'''

class Solution:
    def movingCount(self,threshold,rows,cols):
        if threshold<0 or rows<=0 or cols<=0:
            return 0
        visited = [[0 for i in range(rows)] for j in range(cols)]
        count = self.movingCountCore(threshold,rows,cols,0,0,visited)
        return count

    def movingCountCore(self,threshold,rows,cols,i,j,visited):
        count = 0
        if self.check(threshold,rows,cols,i,j,visited):
                a = visited[1][0]
                visited[i][j] = True
                count = 1+self.movingCountCore(threshold,rows,cols,i-1,j,visited) \
                    +self.movingCountCore(threshold,rows,cols,i+1,j,visited) \
                        +self.movingCountCore(threshold,rows,cols,i,j-1,visited) \
                            +self.movingCountCore(threshold,rows,cols,i,j+1,visited)
        return count

    def check(self,threshold,rows,cols,i,j,visited):
        if 0<=i<rows and 0<=j<cols and self.getDigitSum(i,j)<=threshold \
                and not visited[i][j]:
            return True
        return False
     
    def getDigitSum(self,i,j):
        a = 0
        for index in str(i):
            a += int(index)
        for index in str(j):
            a += int(index)
        return a
if __name__ == '__main__':
    a = Solution()
    print(a.movingCount(10,100,100))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值