j

jaryue

V1

2023/05/04阅读:14主题:默认主题

leetcode 剑指 Offer 13. 机器人的运动范围

leetcode 剑指 Offer 13. 机器人的运动范围.


题目描述

解题思路

剑指 Offer 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/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

法1

方法1:深度优先(递归)\

  1. 我们可以使用深度优先的实现思想来解决这个问题

  2. 机器人的移动位置只有前后左右四个方向,那么我们就判断机器人是否可以移动到该位置

  • 移动规则:1再范围之内
  • 2各位之和小于等于k
  1. 注意已经移动的位置不能再计数,所以要使用一个bool进行标识,是否遍历过
  • 时间复杂度(O(n^2))
  • 空间复杂度(O(n^2))

执行结果

法1

//深度优先
func movingCount(m int, n int, k int) int {
    visited := make([][]bool, m)
    for i := range visited {
        visited[i] = make([]bool, n)
    }
    return dfs(00, m, n, k, visited)
}

func dfs(i, j, m, n, k int, visited [][]bool) int {
//不计数的情况1. 不符合移动规则2. 已经走过了
    if i < 0 || i >= m || j < 0 || j >= n || visited[i][j] || digitSum(i)+digitSum(j) > k {
        return 0
    }
    visited[i][j] = true
    return dfs(i-1, j, m, n, k, visited) +//左位置(可省略)
           dfs(i+1, j, m, n, k, visited) +//右位置
           dfs(i, j-1, m, n, k, visited) +//上走(可省略)
           dfs(i, j+1, m, n, k, visited) + 1//下走
}
//计算各位之和
func digitSum(n int) int {
    sum := 0
    for n > 0 {
        sum += n % 10
        n /= 10
    }
    return sum
}

执行结果: 通过 显示详情 查看示例代码 添加备注

执行用时: 0 ms , 在所有 Go 提交中击败了 100.00% 的用户 内存消耗: 2.8 MB , 在所有 Go 提交中击败了 26.75% 的用户 通过测试用例: 51 / 51 炫耀一下:

优化:

省略左走与上走,因为机器人从0,0开始运动,那么我们让其右下走就可以走完所有的节点,不需要左上运动

//深度优先
func movingCount(m int, n int, k int) int {
    visited := make([][]bool, m)
    for i := range visited {
        visited[i] = make([]bool, n)
    }
    return dfs(00, m, n, k, visited)
}

func dfs(i, j, m, n, k int, visited [][]bool) int {
//不计数的情况1. 不符合移动规则2. 已经走过了
    if i < 0 || i >= m || j < 0 || j >= n || visited[i][j] || digitSum(i)+digitSum(j) > k {
        return 0
    }
    visited[i][j] = true
    return dfs(i+1, j, m, n, k, visited) +//右位置
           dfs(i, j+1, m, n, k, visited) + 1//下走
}
//计算各位之和
func digitSum(n int) int {
    sum := 0
    for n > 0 {
        sum += n % 10
        n /= 10
    }
    return sum
}

分类:

后端

标签:

后端

作者介绍

j
jaryue
V1