持续创作,加速成长!这是我参与「掘金日新计划 · 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;
}
如果你对这道题目还有疑问的话,可以在评论区进行留言;