[路飞]_13. 机器人的运动范围

·  阅读 1517
[路飞]_13. 机器人的运动范围

「这是我参与2022首次更文挑战的第29天,活动详情查看:2022首次更文挑战

剑指 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

题解

错误题解

此处是作者第一印象的错误思路,读者可以不必看这段。

  • 每次可以向左、右、上、下移动一格,没说不能回退,那就是机器人可以随便移动
  • 不能进入行坐标和列坐标的数位之和大于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\x0123456
0012345\color{blue}{5}6
112345\color{blue}{5}67
22345\color{blue}{5}678
3345\color{blue}{5}6789
445\color{blue}{5}6789
55\color{blue}{5}6789
66789
7789
8891
9912
10123
11234

看图可知,机器人从[0,0][0,0]位置出发,被中间的 蓝色的5\color{blue}{5}阻挡,是不能走到 [0,10][0,10] 这个位置的,虽然[0,10][0,10]这个位置行坐标和列坐标的数位之和小于 kk

问题找到了,回归正确的解题思路: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);
         
     }
};
复制代码

其中 helperhelper 方法有什么用呢?

helperhelper主要将整数转换为数位之和,代码如下:

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;
  }
};

复制代码
分类:
前端
收藏成功!
已添加到「」, 点击更改