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

题目描述

在这里插入图片描述

方法一:DFS

思路

使用 visited 记录是否已遍历,然后 DFS 递归遍历:在不满足条件时返回 0,满足时标记该位置,计数加一并递归下去。mysum 计算两个数字的数位和。

代码

class Solution {
public:
    int movingCount(int m, int n, int k) {
        vector<vector<bool>> visited(m, vector<bool>(n, false));
        return dfs(visited, m, n, 0, 0, k);
    }

private:
    int dfs(vector<vector<bool>>& visited, int m, int n, int i, int j, int k) {
        if (i == m || i < 0 || j < 0 || j == n || visited[i][j] || mysum(i, j) > k) {
            return 0;
        }
        visited[i][j] = true;
        return 1 + dfs(visited, m, n, i + 1, j, k)
                 + dfs(visited, m, n, i, j + 1, k)
                 + dfs(visited, m, n, i - 1, j, k)
                 + dfs(visited, m, n, i, j - 1, k);
    }

    int mysum(int x, int y) {
        int sum = 0;
        while (x) {
            sum += x % 10;
            x /= 10;
        }
        while (y) {
            sum += y % 10;
            y /= 10;
        }
        return sum;
    }
};

方法二:BFS

思路

使用 BFS 遍历,借助队列实现 BFS ,首先将 (0,0) 放入队头,然后循环将队头取出,判断是否满足条件(没有越界,没有被访问且数位和小于等于k),若满足条件,则将其加入队尾,然后将队首元素弹出。

代码

class Solution {
public:
    int movingCount(int m, int n, int k) {
        vector<vector<bool>> visited(m, vector<bool>(n, false));
        queue<pair<int, int>> q; // 队列,pair<index of x, index of y>
        pair<int, int> p;
        int cnt = 0;
        q.push(make_pair(0, 0));
        while (!q.empty()) {
            p = q.front();
            int x = p.first;
            int y = p.second;
            if (x != m && y != n && !visited[x][y] && mysum(x, y) <= k) {
                visited[x][y] = true; // 已访问
                ++cnt;
                q.push(make_pair(x + 1, y));
                q.push(make_pair(x, y + 1));
            } 
            q.pop();
        }
        return cnt;
    }

private:
    int mysum(int x, int y) {
        int sum = 0;
        while (x) {
            sum += x % 10;
            x /= 10;
        }
        while (y) {
            sum += y % 10;
            y /= 10;
        }
        return sum;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值