剑指offer: JZ13 机器人的运动范围

Posted 熊熊会发光哦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer: JZ13 机器人的运动范围相关的知识,希望对你有一定的参考价值。

DFS、BFS解决JZ13机器人的运动范围

描述

地上有一个 rows 行和 cols 列的方格。坐标从 [0,0] 到 [rows-1,cols-1] 。一个机器人从坐标 [0,0] 的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 threshold 的格子。 例如,当 threshold 为 18 时,机器人能够进入方格 [35,37] ,因为 3+5+3+7 = 18。但是,它不能进入方格 [35,38] ,因为 3+5+3+8 = 19 。请问该机器人能够达到多少个格子? 输入:1,2,3返回值:3

分析

通过打印这个地图的坐标(0代表可行走1代表不可行走)可以看出,通过回溯dfs的方法就可以计算出所能走的路径,以及不断计算节点周围能走动的节点得出答案bfs,本人采用了两种方案分别实现了本题目

代码

    /**
     * JZ13 机器人的运动范围
     * @param threshold
     * @param rows
     * @param cols
     * @return
     */
    public int movingCount(int threshold, int rows, int cols) {
        int maps[][] = new int[rows][cols];
        //通过输入的值进行地图的二维数组初始化
        for (int i = 0;i<maps.length;i++) {
            for (int j = 0;j<maps[0].length;j++) {
                if ((i/100+i/10+i % 10) + (j/100+j/10+j%10)>threshold)
                    maps[i][j] = 1;
            }
        }
        //打印地图供理解
        for (int i = 0;i<maps.length;i++) {
            for (int j = 0;j< maps[i].length;j++) {
                System.out.print(maps[i][j]);
            }
            System.out.println();
        }
        //初始化地图的每个节点
        MoveMapNode nodesMap[][] = new MoveMapNode[rows][cols];
        for (int i = 0;i<maps.length;i++) {
            for (int j =0;j<maps[i].length;j++) {
                MoveMapNode node = new MoveMapNode(maps[i][j],i,j,maps);
                nodesMap[i][j] = node;
            }
        }

        return movingCountBFS(nodesMap);
    }

    /**
     * bfs实现
     * @param nodesMap
     * @return
     */
    public int movingCountBFS(MoveMapNode nodesMap[][]) {
        Queue<MoveMapNode> nodesQueue = new LinkedList<>();
        nodesQueue.offer(nodesMap[0][0]);
        int count = 1;
        nodesMap[0][0].canVisit = false;
        while (nodesQueue.size()>0) {
            //上
            if (nodesQueue.peek().x > 0 && nodesMap[nodesQueue.peek().x - 1][nodesQueue.peek().y].canVisit == true)  {
                nodesMap[nodesQueue.peek().x - 1][nodesQueue.peek().y].canVisit = false;
                nodesQueue.offer(nodesMap[nodesQueue.peek().x - 1][nodesQueue.peek().y]);
                count ++;
            }
            //下
            if (nodesQueue.peek().x < nodesMap.length - 1 && nodesMap[nodesQueue.peek().x + 1][nodesQueue.peek().y].canVisit == true) {
                nodesMap[nodesQueue.peek().x + 1][nodesQueue.peek().y].canVisit = false;
                nodesQueue.offer(nodesMap[nodesQueue.peek().x + 1][nodesQueue.peek().y]);
                count ++;
            }
            //左
            if (nodesQueue.peek().y > 0 && nodesMap[nodesQueue.peek().x][nodesQueue.peek().y - 1].canVisit == true) {
                nodesMap[nodesQueue.peek().x][nodesQueue.peek().y - 1].canVisit = false;
                nodesQueue.offer(nodesMap[nodesQueue.peek().x][nodesQueue.peek().y - 1]);
                count ++;
            }
            //右
            if (nodesQueue.peek().y < nodesMap[0].length - 1 && nodesMap[nodesQueue.peek().x][nodesQueue.peek().y + 1].canVisit == true) {
                nodesMap[nodesQueue.peek().x][nodesQueue.peek().y + 1].canVisit = false;
                nodesQueue.offer(nodesMap[nodesQueue.peek().x][nodesQueue.peek().y + 1]);
                count ++;
            }
            nodesQueue.poll();
        }

        return count;
    }
    /**
     * dfs实现
     * @param nodesMap
     * @return
     */
    public int movingCountDFS(MoveMapNode nodesMap[][]) {

        Stack<MoveMapNode> stack = new Stack<>();
        stack.push(nodesMap[0][0]);
        int count = 1;
        while (stack.size() > 0) {
            if (stack.peek().x - 1 > 0 && nodesMap[stack.peek().x - 1][stack.peek().y].canVisit == true) {
                //向上判断
                stack.push(nodesMap[stack.peek().x - 1][stack.peek().y]);
                stack.peek().canVisit = false;
                count ++;
            }else if (stack.peek().x + 1 <nodesMap.length && nodesMap[stack.peek().x + 1][stack.peek().y].canVisit == true) {
                //向下判断
                stack.push(nodesMap[stack.peek().x + 1][stack.peek().y]);
                stack.peek().canVisit = false;
                count ++;
            }else if (stack.peek().y - 1 > 0 && nodesMap[stack.peek().x][stack.peek().y - 1].canVisit == true) {
                //向左判断
                stack.push(nodesMap[stack.peek().x][stack.peek().y - 1]);
                stack.peek().canVisit = false;
                count ++;
            }else if (stack.peek().y + 1 <  nodesMap[0].length && nodesMap[stack.peek().x][stack.peek().y + 1].canVisit == true) {
                //向右判断
                stack.push(nodesMap[stack.peek().x][stack.peek().y + 1]);
                stack.peek().canVisit = false;
                count ++;
            }else {
                stack.pop();
            }
        }
        return count;
    }

    /**
     * 每个节点的实体类
     */
    class MoveMapNode{
        int number;
        int x;
        int y;

        boolean canVisit = true;

        //如果当前节点为1就代表不能走动,置canVisit为false
        MoveMapNode(int number,int x,int y,int[][]map) {
            this.number = number;
            this.x = x;
            this.y = y;

            if (number == 1) {
                canVisit = false;
            }
        }
    }

剑指OFFER 机器人的运动范围

剑指OFFER 机器人的运动范围

矩形搜索的变形,可以深搜,也可以广搜. 思维上没有什么难度,但是需要细心.

深搜代码

class Solution {
public:
    
    int counter = 0;
    vector<pair<int,int> > rotate_fac;
    int m_threshold;
    int m_rows;
    int m_cols;
    vector<vector<bool> > matrix;

    bool check(int x,int y)
    {
        int sum = 0;
        int xx = x;
        int yy = y;
        while (xx != 0) {
            sum += xx % 10;
            xx /= 10;
        }
        while (yy != 0) {
            sum += yy % 10;
            yy /= 10;
        }
        if(x>=0 && y>=0 && x<m_rows && y<m_cols && matrix[x][y]==false && sum <= m_threshold)return true;
        else return false;
    }
    
    void recur(int x,int y)
    {
        matrix[x][y]=true;
        counter++;
        for(int i=0;i<4;i++)
        {
            if(check(x+rotate_fac[i].first,y+rotate_fac[i].second))
            {
                recur(x+rotate_fac[i].first,y+rotate_fac[i].second);
            }
        }
    }

    int movingCount(int threshold, int rows, int cols)
    {
        //handling special cases
        if (rows == 0 || cols == 0 || threshold < 0)return 0;

        //initialize
        counter = 0;
        m_threshold =  threshold;
        m_rows = rows;
        m_cols = cols;
        rotate_fac.push_back(pair<int,int>(0,1));
        rotate_fac.push_back(pair<int,int>(1,0));
        rotate_fac.push_back(pair<int,int>(0,-1));
        rotate_fac.push_back(pair<int,int>(-1,0));
        matrix.resize(rows);
        for(int i=0;i<rows;i++)
        {
            matrix[i].resize(cols);
        }
        
        recur(0,0);
        
        return counter;
    }
};

以上是关于剑指offer: JZ13 机器人的运动范围的主要内容,如果未能解决你的问题,请参考以下文章

《剑指Offer——12.矩阵中的路径,13.机器人的运动范围》代码

LeetCode(剑指 Offer)- 13. 机器人的运动范围

剑指OFFER----试题13. 机器人的运动范围

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

剑指 Offer(C++版本)系列:剑指 Offer 13 机器人的运动范围

剑指 Offer(C++版本)系列:剑指 Offer 13 机器人的运动范围