【LeetCode】每日一题 面试题13. 机器人的运动范围

83 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情

[面试题13. 机器人的运动范围](leetcode.cn/problems/ma…)

地上有一个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

解题思路

深度优先搜索 + 剪枝
由题可知,机器人只能往右或者往下移动
当机器人移动时,需要查看要移动到的格子下标数位和是否大过 k,大了话就不给移动(提前进行剪枝返回)
对于移动到过的格子,要做 true 处理
代码讲解
先新建一个 m 行 n 列的数组,全部初始化为 false
进行深度优先遍历,如果索引越界、i 和 j 的数位和大于 k、该格子已遍历过,那么提前剪枝,返回0
如果符合条件,将数组该格子变为 true,代表已遍历
继续进行递归,往右的和往下的,同时将递归的返回值 连同 + 1 进行返回

代码实现

/**
 * @param {number} m
 * @param {number} n
 * @param {number} k
 * @return {number}
 */
var movingCount = function(m, n, k) {
    const visited = Array(m).fill(0).map(() => Array(n).fill(false));
    const dfs = (i, j) => {
        if(i >= m || j >= n || sum(i) + sum(j) > k || visited[i][j])
            return 0;
        visited[i][j] = true;
        return 1 + dfs(i + 1, j) + dfs(i, j + 1);
    }
​
    return dfs(0, 0);
};
​
const sum = (num) =>{
    let total = 0;
    while(num) {
        total += num % 10;
        num = Math.floor(num / 10);
    }
    return total;
}

如果你对这道题目还有疑问的话,可以在评论区进行留言;