2021/4/6 剑指 Offer 13. 机器人的运动范围 bfs+queue

124 篇文章 1 订阅
53 篇文章 0 订阅

bfs

class Solution {
public:
    int getSum(int num) {
        int sum = 0;
        while (num != 0) {
            sum += num % 10;
            num /= 10;
        }
        return sum;
    }
    int movingCount(int m, int n, int k) {
        // k等于0,只有左上角位置满足要求
        if (k == 0) return 1;
        // visited标记当前位置是否已经被搜索过
        // 搜索过为true,没有则为false
        vector<vector<bool> > visited(m, vector<bool>(n, false));
        int retNum = 0; // 机器人能运动的格子数
        queue<vector<int> > q; // 创建存储vector<int>元素的队列
        // 将容器初始化为长度为3的数组,数组中每个位置都为0
        // 0位置元素为当前遍历位置的横坐标,1位置元素为当前遍历位置的纵坐标,2位置为当前遍历位置的坐标和
        // 即初始化的vector容器代表的就是左上角第一个位置元素
        vector<int> init = {0, 0, 0}; 
        // 左上角位置入队
        q.push(init);
        while (q.size() > 0) {
            // 取出队列首部元素
            vector<int> vec = q.front();
            q.pop();
            // 获取队列首部元素代表的位置信息
            int x = vec[0], y = vec[1], sum = vec[2];
            // 判断若遍历的位置越界、坐标和大于k、当前位置已经遍历
            // 直接进行下一轮循环
            if (x >= m || y >= n || k < sum || visited[x][y]) continue;
            // 否则将当前位置标记为已经遍历
            visited[x][y] = true;
            // 机器人活动范围加一
            retNum++;
            // 将当前遍历位置的右边和下边的位置入队
            // 这样在while循环中,就能广度遍历所有的位置
            q.push({x + 1, y, getSum(x + 1) + getSum(y)});
            q.push({x, y + 1, getSum(x) + getSum(y + 1)}); 
        }
        return retNum;

    }
};

作者:RyanWangllng
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/zhu-shi-xing-ti-jie-shen-du-you-xian-sou-lokj/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

dfs

这个讲的贼好
https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/dfshe-bfsliang-chong-jie-jue-fang-shi-by-sdwwld/

DFS:深度优先搜索



在这里插入图片描述









这个图讲的很好 但是底下的程序讲的不行
贴一个自己写的:
注意:c++里二维数组不能bool visited[m][n]这样传参
vector<vector<bool>> visited(m, vector<bool>(n, 0));代表一个二维矩阵,m行,每行有n个0

class Solution {
public:
    int movingCount(int m, int n, int k) {
       // bool visited[m][n];
        vector<vector<bool>> visited(m, vector<bool>(n, 0));
        return dfs(0,0,m,n,k,visited);
    }
    int dfs(int i,int j,int m,int n,int k,vector<vector<bool>>& visited){//这个地方传参注意
        if(i>=m||j>=n||summ(i,j)>k||visited[i][j]) return false;
        visited[i][j]=true;
        return 1+dfs(i+1,j,m,n,k,visited)+dfs(i,j+1,m,n,k,visited);
    }
    int summ(int i,int j){
        int sum = 0;
        while (i != 0) {
            sum += i % 10;
            i /= 10;
        }
        while (j != 0) {
            sum += j % 10;
            j /= 10;
        }
        return sum;  

    }
};

/*class Solution {
public:
    int movingCount(int m, int n, int k) {
        vector<vector<bool>> visited(m, vector<bool>(n, 0));
        return dfs(0, 0, 0, 0, visited, m, n, k);
    }
private:
    int dfs(int i, int j, int si, int sj, vector<vector<bool>> &visited, int m, int n, int k) {
        if(i >= m || j >= n || k < si + sj || visited[i][j]) return 0;
        visited[i][j] = true;
        return 1 + dfs(i + 1, j, (i + 1) % 10 != 0 ? si + 1 : si - 8, sj, visited, m, n, k) +
                   dfs(i, j + 1, si, (j + 1) % 10 != 0 ? sj + 1 : sj - 8, visited, m, n, k);
    }
};

作者:jyd
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/mian-shi-ti-13-ji-qi-ren-de-yun-dong-fan-wei-dfs-b/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/

BFS:广度优先搜索










public int movingCount(int m, int n, int k) {
    //临时变量visited记录格子是否被访问过
    boolean[][] visited = new boolean[m][n];
    int res = 0;
    //创建一个队列,保存的是访问到的格子坐标,是个二维数组
    Queue<int[]> queue = new LinkedList<>();
    //从左上角坐标[0,0]点开始访问,add方法表示把坐标
    // 点加入到队列的队尾
    queue.add(new int[]{0, 0});
    while (queue.size() > 0) {
        //这里的poll()函数表示的是移除队列头部元素,因为队列
        // 是先进先出,从尾部添加,从头部移除
        int[] x = queue.poll();
        int i = x[0], j = x[1];
        //i >= m || j >= n是边界条件的判断,k < sum(i, j)判断当前格子坐标是否
        // 满足条件,visited[i][j]判断这个格子是否被访问过
        if (i >= m || j >= n || k < sum(i, j) || visited[i][j])
            continue;
        //标注这个格子被访问过
        visited[i][j] = true;
        res++;
        //把当前格子右边格子的坐标加入到队列中
        queue.add(new int[]{i + 1, j});
        //把当前格子下边格子的坐标加入到队列中
        queue.add(new int[]{i, j + 1});
    }
    return res;
}

//计算两个坐标数字的和
private int sum(int i, int j) {
    int sum = 0;
    while (i != 0) {
        sum += i % 10;
        i /= 10;
    }
    while (j != 0) {
        sum += j % 10;
        j /= 10;
    }
    return sum;
}

作者:sdwwld
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/dfshe-bfsliang-chong-jie-jue-fang-shi-by-sdwwld/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值