(搜索) 剑指 Offer 13. 机器人的运动范围 ——【Leetcode每日一题】

❓剑指 Offer 13. 机器人的运动范围

难度:中等

地上有一个 mn 列的方格,从坐标 [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 的格子看作障碍物,那么这道题就是一道很传统的搜索题目,我们可以使用广度优先搜索或者深度优先搜索来解决它,本文选择使用 广度优先搜索 的方法来讲解。

那么如何计算一个数的数位之和呢?

  • 我们只需要对数 x 每次对 10 取余,就能知道数 x 的个位数是多少,然后再将 x 除 10,这个操作等价于将 x 的十进制数向右移一位,删除个位数(类似于二进制中的 >> 右移运算符),不断重复直到 x 为 0 时结束。

🍁代码:(C++、Java)

C++

cpp 复制代码
class Solution {
private:
    int getsum(int x){
        int ans = 0;
        while(x > 0 ){
            ans += x % 10;
            x /= 10;
        }
        return ans;
    }
public:
    int movingCount(int m, int n, int k) {
        if(k == 0) return 1;
        vector<pair<int, int>> dirs{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        queue<pair<int, int>> q;
        q.push(make_pair(0, 0));
        vector<vector<int>> visited(m, vector<int>(n));
        visited[0][0] = 1;
        int ans = 1;
        while(!q.empty()){
            auto [x, y] = q.front();
            q.pop();
            for(auto dir : dirs){
                int cur_x = x + dir.first, cur_y = y + dir.second;
                if(cur_x < 0 || cur_x >= m || cur_y < 0 || cur_y >= n || visited[cur_x][cur_y] || getsum(cur_x) + getsum(cur_y) > k) continue;
                q.push(make_pair(cur_x, cur_y));
                visited[cur_x][cur_y] = 1;
                ans++;
            }
        }
        return ans;
    }
};

Java

java 复制代码
class Solution {
    private int getsum(int x){
        int ans = 0;
        while(x > 0 ){
            ans += x % 10;
            x /= 10;
        }
        return ans;
    }
    public int movingCount(int m, int n, int k) {
        if(k == 0) return 1;
        int[][] dirs = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        Queue<int[]> q = new LinkedList<int[]>();
        q.offer(new int[]{0, 0});
        int[][]  visited = new int[m][n];
        visited[0][0] = 1;
        int ans = 1;
        while(!q.isEmpty()){
            int[] cell = q.poll();
            for(int[] dir : dirs){
                int cur_x = cell[0] + dir[0], cur_y = cell[1] + dir[1];
                if(cur_x < 0 || cur_x >= m || cur_y < 0 || cur_y >= n || visited[cur_x][cur_y] == 1 || getsum(cur_x) + getsum(cur_y) > k) continue;
                q.offer(new int[]{cur_x, cur_y});
                visited[cur_x][cur_y] = 1;
                ans++;
            }
        }
        return ans;
    }
}

🚀 运行结果:

🕔 复杂度分析:

  • 时间复杂度 : O ( m n ) O(mn) O(mn),其中 m 为方格的行数,n 为方格的列数。考虑所有格子都能进入,那么搜索的时候一个格子最多会被访问的次数为常数,所以时间复杂度为 O ( 4 m n ) = O ( m n ) O(4mn) = O(mn) O(4mn)=O(mn)。
  • 空间复杂度 : O ( m n ) O(mn) O(mn),搜索的时候需要一个大小为 O ( m n ) O(mn) O(mn), 的标记结构用来标记每个格子是否被走过。

题目来源:力扣。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN---力扣专栏,每日更新!

注: 如有不足,欢迎指正!

相关推荐
杜杜的man3 分钟前
【go从零单排】迭代器(Iterators)
开发语言·算法·golang
小沈熬夜秃头中୧⍤⃝19 分钟前
【贪心算法】No.1---贪心算法(1)
算法·贪心算法
粤海科技君23 分钟前
如何使用腾讯云GPU云服务器自建一个简单的类似ChatGPT、Kimi的会话机器人
服务器·chatgpt·机器人·腾讯云
木向1 小时前
leetcode92:反转链表||
数据结构·c++·算法·leetcode·链表
阿阿越1 小时前
算法每日练 -- 双指针篇(持续更新中)
数据结构·c++·算法
skaiuijing1 小时前
Sparrow系列拓展篇:对调度层进行抽象并引入IPC机制信号量
c语言·算法·操作系统·调度算法·操作系统内核
Star Patrick1 小时前
算法训练(leetcode)二刷第十九天 | *39. 组合总和、*40. 组合总和 II、*131. 分割回文串
python·算法·leetcode
武子康3 小时前
大数据-214 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn n_clusters labels
大数据·人工智能·python·深度学习·算法·机器学习·数据挖掘
m0_571957585 小时前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
pianmian18 小时前
python数据结构基础(7)
数据结构·算法