剑指Offer -- 机器人的运动范围

机器人的运动范围

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

//方法一:采用递归求解
public int movingCount(int threshold, int rows, int cols){
        boolean [][] visit = new boolean[rows][cols];  //自动初始化为false
        return countingSteps(threshold,rows,cols,0,0,visit);
}
private int countingSteps(int limit, int rows, int cols, int r, int c,boolean[][] visit) {
    if(  r < 0 || c < 0 || r >= rows || c >= cols || visit[r][c] == true 
        || bitSum(r)+bitSum(c) > limit )
        return 0;
    visit[r][c] = true; 
    return countingSteps(limit,rows,cols,r+1,c,visit)+
           countingSteps(limit,rows,cols,r-1,c,visit)+
           countingSteps(limit,rows,cols,r,c+1,visit)+
           countingSteps(limit,rows,cols,r,c-1,visit)+1;
}
private int bitSum(int i){
    int count = 0;
    while( i > 0){
        count += i % 10;
        i = i / 10;
    }
    return count;
}

//方法二:使用非递归DFS求解
//需要记录已经遍历过的节点,用辅助矩阵visit[rows * cols]
public int movingCount(int threshold, int rows, int cols){
    if(rows <= 0 || cols <= 0 || threshold < 0) return 0; 
    boolean [] visit = new boolean [rows*cols];  //为了配合栈使用
    Stack <Integer> s = new  Stack <Integer> ();
    int[][] xoy = {{0,1,0,-1},{1,0,-1,0}};
    int count = 0;

    s.push(0);
    visit[0] = true;
    while(!s.empty()){
        int cur = s.pop();
        count++ ;
        for(int i = 0; i < 4; i++){
            int x = cur % cols + xoy[0][i];
            int y = cur / cols + xoy[1][i];
            if( x>=0 && y>=0 && x<cols && y<rows &&
                !visit[x+y*cols] && bitSum(x)+bitSum(y)<=threshold){
            s.push(x+y*cols);
            visit[x+y*cols] = true;
        }
    } 
   return count;
}

猜你喜欢

转载自blog.csdn.net/liuheng94/article/details/81606597