剑指offer——机器人的运动范围(还行)

来源:互联网 发布:淘宝宝贝图片素材 编辑:程序博客网 时间:2024/06/07 05:59

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

思路:

机器人可以重复进入格子,所以当碰到无法进入的格子后,可以原路返回。虽然可以重复进入格子,但碰到已经访问过的,必须退出,否则会无限循环!!


public class Solution {    public int movingCount(int threshold, int rows, int cols) {        int[] visit = new int[rows*cols];        return helper(threshold, rows, cols, 0, 0 ,visit);    }    public int helper(int threshold, int rows, int cols, int r, int c, int[] visit) {        if (r > rows - 1 || r < 0 || c > cols - 1 || c < 0 || calculate(r, c) > threshold|| visit[r*cols+c]==1)            return 0;        visit[r*cols+c] = 1;        return 1 + helper(threshold, rows, cols, r + 1, c, visit) + helper(threshold, rows, cols, r - 1, c,visit) + helper(threshold, rows, cols, r, c + 1,visit) + helper(threshold, rows, cols, r, c - 1,visit); //为什么这里是加号?因为机器人可以原路返回来重走线路扩大运动范围,所以这个范围内最大路径都可以通过(r,c)这个点连通,同时visit标志的存在又保证了不会进入相同的点,所以直接相加    }    public int calculate(int r, int c) {        int result = 0;        while (r != 0) {            result += r % 10;            r /= 10;        }        while (c != 0) {            result += c % 10;            c /= 10;        }        return result;    }}

如果机器人不能回退,转换成求单次最大的路径(dfs,时间复杂度会很大)

    public int movingCount(int threshold, int rows, int cols)    {        if(threshold<0)            return 0;        if(threshold==0)            return 0;        boolean[][] visited = new boolean[rows][cols];        return go(threshold,0,0,rows,cols,visited);    }    public int go(int threshold, int i, int j, int rows, int cols, boolean[][] visited){        if(i>=rows||i<0||j>=cols||j<0||calculate(i,j)>threshold||visited[i][j]==true)            return 0;        visited[i][j] = true;        int a = go(threshold,i+1,j,rows,cols,visited)+1;        int b = go(threshold,i-1,j,rows,cols,visited)+1;        int c = go(threshold,i,j+1,rows,cols,visited)+1;        int d = go(threshold,i,j-1,rows,cols,visited)+1;        visited[i][j] = false;        return (int)Math.max(Math.max(Math.max(a,b),c),d);    }
原创粉丝点击