「这是我参与2022首次更文挑战的第29天,活动详情查看:2022首次更文挑战」
题目
地上有一个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的格子,统计一下行坐标和列坐标的数位之和小于等于k的格子不久完了吗?这怎么还难度中等了呢?
代码如下:
var movingCount = function (m, n, k) {
let result = 0;
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
const t = heler(i) + heler(j);
if (t <= k) result++;
}
}
return result;
function helper(x) {
let num = 0;
while (x >= 1) {
num += x % 10;
x = Math.floor(x / 10);
}
return num;
}
};
复制代码
感觉也没啥问题啊,编辑,执行,提交;通过测试用例2 / 49
我怕是个二傻子吧。检查一下哪里错了?
y\x | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
0 | 0 | 1 | 2 | 3 | 4 | 6 | |
1 | 1 | 2 | 3 | 4 | 6 | 7 | |
2 | 2 | 3 | 4 | 6 | 7 | 8 | |
3 | 3 | 4 | 6 | 7 | 8 | 9 | |
4 | 4 | 6 | 7 | 8 | 9 | ||
5 | 6 | 7 | 8 | 9 | |||
6 | 6 | 7 | 8 | 9 | |||
7 | 7 | 8 | 9 | ||||
8 | 8 | 9 | 1 | ||||
9 | 9 | 1 | 2 | ||||
10 | 1 | 2 | 3 | ||||
11 | 2 | 3 | 4 |
看图可知,机器人从位置出发,被中间的 蓝色的阻挡,是不能走到 这个位置的,虽然这个位置行坐标和列坐标的数位之和小于
问题找到了,回归正确的解题思路:DFS
正确题解 DFS
DFS伪代码
var movingCount = function (m, n, k) {
// 机器人从[0,0]位置出发
dfs(0,0)
function dfs(i,j){
// i表示机器人所在行坐标
// j 表示机器人坐在列坐标
// 行坐标和列坐标的数位之和大于 k 终止递归
if( helper(i) + helper(j) > k) return;
// i,j越界,终止递归
if(i < 0 || i >= m || j < 0 || j >=n) return
dfs(i+1,j);
dfs(i-1,j);
dfs(i,j-1);
dfs(i,j+1);
}
};
复制代码
其中 方法有什么用呢?
主要将整数转换为数位之和,代码如下:
function helper(x) {
let num = 0;
while (x >= 1) {
num += x % 10;
x = Math.floor(x / 10);
}
return num;
}
复制代码
根据上述 DFS 思想编辑代码如下:
完整代码
var movingCount = function (m, n, k) {
let result = 0;
let array = Array(m);
for (let i = 0; i < m; i++) {
array[i] = Array(n).fill(0);
}
dfs(0, 0, k);
return result;
function dfs(i, j, k) {
if (
i >= 0 &&
j >= 0 &&
i < m &&
j < n &&
array[i][j] !== 1 &&
helper(i) + helper(j) <= k
) {
result++;
const low = [-1, 1, 0, 0];
const row = [0, 0, -1, 1];
array[i][j] = 1;
for (let s = 0; s < 4; s++) {
const x = i + low[s];
const y = j + row[s];
dfs(x, y, k);
}
}
}
function helper(x) {
let num = 0;
while (x >= 1) {
num += x % 10;
x = Math.floor(x / 10);
}
return num;
}
};
复制代码