[剑指Offer] 13_机器人的运动范围

题目

地上有一个m行n列的方格。一个机器人从坐标(0,0)的格子开始移动,他每次可以向左、右、上、下移动一格,但不能进入行坐标和列坐标的数位之和大于k的格子。请问该机器人能够到达多少个格子?

例:

当k为18时,机器人能够进入(35, 37),因为3+5+3+7=18。但它不能进入放个(35, 38),
因为3+5+3+8=19。


思路

  1. 回溯法。和题12同样进入一格后递归处理向其上下左右移动的情况,同时用一个二维数组保存处理过的情况记录。
    1. 时间复杂度:最坏情况,每一格都能到达,O(m*n)
    2. 空间复杂度:用来保存的历史记录O(m*n),递归深度O(max(m,n))
  2. 广度优先搜索:从左上角开始,按斜线处理情况。每一步都只考虑向右或者向下移动的情况,因为向上或者向下的情况等于上一步中另外一个解。 详见代码。
    1. 时间复杂度:O(m*n)
    2. 空间复杂度:保存当前解情况O(max(m,n))

代码

思路2:时间复杂度O(m,n),空间复杂度O(max(m,n))

def robot_move(row, col, k):
    """
    :param row: row of matrix, m
    :param col: col of matrix, n
    :param k: bit sum limit
    :return: num of blocks can reach
    """
    def bit_sum(num):
        """
        calculate bit sum
        :param num: num
        :return: bit sum
        """
        b_sum = 0
        while num:
            b_sum += num % 10
            num = num // 10
        return b_sum

    if row < 1 or col < 1:
        raise Exception('Invalid Matrix')

    to_check = [(0,0)]
    next_check = set() # to remove the duplication
    block_count = 0
    while to_check:
        i_cur, j_cur = to_check.pop(0)
        block_count += 1
        if j_cur + 1 < col and bit_sum(i_cur) + bit_sum(j_cur + 1) <= k:
        	# move right
            next_check.add((i_cur, j_cur+1))
        if i_cur + 1 < row and bit_sum(i_cur + 1) + bit_sum(j_cur) <= k:
            # move down
            next_check.add((i_cur + 1, j_cur))
        if not to_check: 
            to_check.extend(list(next_check))
            next_check = set()
    return block_count

思考

  1. 求各位数字之和不知道有没有什么更好的方法,有助于加速。
  2. 我的解法中利用集合的不重复特点(实际上是一个哈希表)去除重复的解,如果元素很多的时候,当哈希表每次复制扩大会消耗许多时间。
    但是实际上每次的to_check都是从右上有序排列到左下角的,是否可以利用这点,直接处理。
  3. 本题没有跑测试用例,只检测了边界、特殊输入,因为测试用例得自己算很烦,希望这本书以后可以配套测试库。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值