首页 > 其他 > 详细

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

时间:2020-12-28 23:59:27      阅读:43      评论:0      收藏:0      [点我收藏+]

问题描述:

地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格[35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

解题思路:

本题与矩阵中的路径类似,是典型的搜索 & 回溯问题。在介绍回溯算法算法前,为提升计算效率,首先讲述两项前置工作:数位之和计算、可达解分析 。

数位之和计算:
设一数字x,向下取整除法符号// ,求余符号 ,则有:

  • x⊙10:得到x的个位数字;
  • x//10: 令x的十进制数向右移动一位,即删除个位数字。

由于机器人每次只能移动一格(即只能从x运动至x±1),因此每次只需计算xx±1的数位和增量。本题说明1≤n,m≤100 ,以下公式仅在此范围适用。

(x + 1) % 10 != 0 ? s_x + 1 : s_x - 8;

方法:广度优先遍历 BFS

  • BFS/DFS : 两者目标都是遍历整个矩阵,不同点在于搜索顺序不同。

    • DFS 是朝一个方向走到底,再回退,以此类推;

    • BFS 则是按照“平推”的方式向前搜索。

  • BFS 实现: 通常利用队列实现广度优先遍历。

算法解析:

  • 初始化: 将机器人初始点 (0, 0)(0,0) 加入队列 queue ;

  • 迭代终止条件: queue 为空。代表已遍历完所有可达解。

  • 迭代工作:

    • 单元格出队: 将队首单元格的 索引、数位和 弹出,作为当前搜索单元格。
    • 判断是否跳过: 若 ① 行列索引越界 或 ② 数位和超出目标值 k 或 ③ 当前元素已访问过 时,执行 continue 。
    • 标记当前单元格 :将单元格索引 (i, j) 存入 Set visited 中,代表此单元格 已被访问过 。
    • 单元格入队: 将当前元素的 下方、右方 单元格的 索引、数位和 加入 queue 。
  • 返回值: Set visited 的长度 len(visited) ,即可达解的数量。
    PS:使用了辅助变量 res 统计可达解数量;

class Solution {
public:
    int movingCount(int m, int n, int k) {
        vector<vector<bool>> v(m, vector<bool>(n, 0));
        int res = 0;
        queue<vector<int>> que;
        que.push({0, 0, 0, 0});
        while(!que.empty())
        {
            auto x = que.front();
            que.pop();
            int i = x[0], j = x[1], si = x[2], sj = x[3];
            if (i >= m || j >= n || k < si + sj || v[i][j]) continue;
            ++res;
            v[i][j] = true;
            que.push({i, j + 1, si, (j + 1) % 10 ? (sj + 1) : (sj - 8)});
            que.push({i + 1, j, (i + 1) % 10 ? (si + 1) : (si - 8), sj});
        }
        return res;
    }
};

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

原文:https://www.cnblogs.com/zeroluo/p/14203932.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!