机器人的运动范围

机器人的运动范围

http://www.nowcoder.com/questionTerminal/6e5207314b5241fb83f2329e89fdecc8

个人想法,有错误请批!

题目描述

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

思路

这道题我先是用BFS(广搜)的思路去解决的,BFS一般是用来查找源点到目的结点之间的最短路径,它的实现思路是通过一个点往外扩散,然后外层点再往外扩散,一直持续下去,直到碰到目的结点,那么扩散的层次一定是最小的,可以幻想成一颗石头丢进水里,水的波纹不停往外扩,而这道题可以利用bfs扩散的特点,不停往外扩散,记录扩散走过的格子数,直到不能扩为止,答案就over了。
至于DFS(深搜)的思路,也是可以解决的,就是一路走到黑,走到死胡同再退回一步,从另一个方向一路走到黑,重复以上过程,直到全部可走方格都走完为止。可以递归、可以非递归(用栈实现)

代码实现

递归版本实现DFS

/**
     * 递归版本实现dfs
     * @param threshold
     * @param rows
     * @param cols
     * @return
     */
    public int movingCount2(int threshold, int rows, int cols) {
        if (threshold < 0 || rows <= 0 || cols <= 0)
            return 0;
        boolean[][] visited = new boolean[rows][cols];
        return dfs(threshold, 0, 0, rows, cols, visited);
    }

    private int dfs(int threshold, int x, int y, int rows, int cols, boolean[][] visited) {
        //先判断当前结点是否可以走
        if(judge(x,y, visited, rows,cols, threshold)){
            visited[x][y] = true;
            //获取从(x,y)四个方位出发,可以走的路径长度
            return 1 + dfs(threshold, x -1, y, rows, cols, visited) + //上
                    dfs(threshold, x , y + 1, rows, cols, visited) + //右
                    dfs(threshold, x +1, y, rows, cols, visited) +//下
                    dfs(threshold, x , y - 1, rows, cols, visited);//左
        }else {
            //以当前结点不能进行扩散,则路径长度为0
            return 0;
        }
    }
/**
     * 判断(x,y)方块是否可以走
     *
     * @param x
     * @param y
     * @param visited
     * @param rows
     * @param cols
     * @return
     */
    private boolean judge(int x, int y, boolean[][] visited, int rows, int cols, int threshold) {
        //getSum(x, y) > threshold判断位数和是否符合条件
        if (x < 0 || x >= rows || y < 0 || y >= cols || visited[x][y] == true || getSum(x, y) > threshold)
            return false;
        else
            return true;
    }

    private int getSum(int x, int y) {
        //获取x,y坐标的位数和
        int sum = 0;
        while (x % 10 != 0) {
            sum += x % 10;
            x = x / 10;
        }
        while (y % 10 != 0) {
            sum += y % 10;
            y = y / 10;
        }
        return sum;
    }

BFS版本,使用队列保存走过的点

    public int movingCount(int threshold, int rows, int cols) {
        if (threshold < 0 || rows <= 0 || cols <= 0)
            return 0;
        boolean[][] visited = new boolean[rows][cols];
        ArrayList<Integer> paths = new ArrayList<>();
        int count = 0;
        //将(0,0)结点进队
        paths.add(0);
        count++;
        visited[0][0] = true;
        while (paths.size() > 0) {
            //取出队首
            int heap = paths.remove(0);
            //找出上下左右四个可以走过的方块
            //heap一维坐标先转成二维坐标
            int x = heap / cols;
            int y = heap % cols;
            int x1 = 0, y1 = 0;//下一个方块的坐标
            int dict = 0;
            while (dict <= 3) {
                switch (dict) {
                    case 0:
                        x1 = x - 1;
                        y1 = y;
                        break;
                    case 1:
                        x1 = x;
                        y1 = y + 1;
                        break;
                    case 2:
                        x1 = x + 1;
                        y1 = y;
                        break;
                    case 3:
                        x1 = x;
                        y1 = y - 1;
                        break;
                }
                if (judge(x1, y1, visited, rows, cols, threshold)) {
                    //当前方块可以走,进队
                    count++;
                    visited[x1][y1] = true;
                    paths.add(x1 * cols + y1);
                }
                dict++;
            }
        }
        return count;
    }

    /**
     * 判断(x,y)方块是否可以走
     *
     * @param x
     * @param y
     * @param visited
     * @param rows
     * @param cols
     * @return
     */
    private boolean judge(int x, int y, boolean[][] visited, int rows, int cols, int threshold) {
        //getSum(x, y) > threshold判断位数和是否符合条件
        if (x < 0 || x >= rows || y < 0 || y >= cols || visited[x][y] == true || getSum(x, y) > threshold)
            return false;
        else
            return true;
    }

    private int getSum(int x, int y) {
        //获取x,y坐标的位数和
        int sum = 0;
        while (x % 10 != 0) {
            sum += x % 10;
            x = x / 10;
        }
        while (y % 10 != 0) {
            sum += y % 10;
            y = y / 10;
        }
        return sum;
    }
全部评论

相关推荐

11-24 00:11
已编辑
广东工业大学 算法工程师
避雷深圳&nbsp;&nbsp;yidao,试用期&nbsp;6&nbsp;个月。好嘛,试用期还没结束,就直接告诉你尽快找下一家吧,我谢谢您嘞
牛客75408465号:笑死,直属领导和 hr 口径都没统一,各自说了一些离谱的被裁理由,你们能不能认真一点呀,哈哈哈哈哈😅😅😅
点赞 评论 收藏
分享
三年之期已到我的offer快到碗里来:9硕都比不上9本
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务