Sword Finger Offer 13. Robot's range of motion-breadth first search, recursion

1. Title

There is a square with m rows and n columns on the ground, from coordinates [0,0] to coordinates [m-1,n-1]. A robot starts to move from the grid of coordinates [0, 0]. It can move one grid to the left, right, up, and down at a time (cannot move outside the grid), and cannot enter the sum of row coordinates and column coordinates greater than k lattice. For example, when k is 18, the robot can enter the square [35, 37] because 3+5+3+7=18. But it cannot enter square [35, 38] because 3+5+3+8=19. How many grids can the robot reach?

Second, problem solution 1-recursive realization

Search in four directions

class Solution {
    
    

    public int dig_num(int target){
    
    
        int sum = 0;
        while(target>0){
    
    
            sum+=target%10;
            target/=10;
        }

        return sum;
    }

    public int dfsSolver(int startL,int startR,int m,int n,int k,int[][] visited){
    
    
        if(startL<0||startR<0||startL>=m||startR>=n||dig_num(startL)+dig_num(startR)>k||visited[startL][startR]==1){
    
    
            return 0;
        }
        visited[startL][startR]=1;
        return 1+dfsSolver(startL-1,startR,m,n,k,visited)+dfsSolver(startL+1,startR,m,n,k,visited)+dfsSolver(startL,startR-1,m,n,k,visited)+dfsSolver(startL,startR+1,m,n,k,visited);
    }

    public int movingCount(int m, int n, int k) {
    
    
        int[][] visited = new int[m][n];
        return dfsSolver(0,0,m,n,k,visited);
    }
}

Problem solution instructions

We consider the grid with row coordinates and column coordinates greater than k as obstacles, then this question is a very traditional search question, we can use breadth first search or depth first search to solve it, this article chooses to use breadth first The search method is explained.

So how to calculate the sum of the digits of a number? We only need to take the remainder of the number x to 10 each time, we can know what the unit digit of the number x is, and then divide x by 10. This operation is equivalent to shifting the decimal number of x by one place to the right and deleting The number of digits (similar to the >> right shift operator in binary), and repeats until the end of x is 0.

At the same time, there is a hidden optimization for this problem: we can reduce the search direction to right and down during the search process, instead of searching up and left. As shown in the figure below, we show the 16 * 16 map with the enlargement of the restriction condition k, the change trend of the feasible squares. The value in each square is the sum of the row and column coordinates. The blue square represents non-obstacles. Square, that is, its value is less than or equal to the current restriction condition k. We can find that as the restriction condition k increases, the newly added non-obstacle squares in the blue square area where (0, 0) is located can be obtained by moving the upper or left square one step. The other disconnected blue grid areas will be connected as k increases, and when they are connected, they are also obtained by moving the upper or left grid one step, so we can reduce our search direction to right or to under.

Three, problem solution 2-breadth first search

class Solution {
    
    

    public int dig_num(int target){
    
    
        int sum = 0;
        while(target>0){
    
    
            sum+=target%10;
            target/=10;
        }

        return sum;
    }

    public int movingCount(int m, int n, int k) {
    
    
        if(k==0){
    
    
            return 1;
        }

        int[] dx = {
    
    1,0};
        int[] dy = {
    
    0,1};
        int[][] visited = new int[m][n];
        visited[0][0] = 1;
        Queue<int[]> queue = new LinkedList<int[]>();

        queue.add(new int[]{
    
    0,0});
        int res=1;
        while(!queue.isEmpty()){
    
    
            int[] cell = queue.poll();
            int x = cell[0];
            int y = cell[1];

            for(int i=0;i<2;i++){
    
    
                int tx = x+dx[i];
                int ty = y+dy[i];
                if(tx<0||tx>=m||ty<0||ty>=n||dig_num(tx)+dig_num(ty)>k||visited[tx][ty]==1){
    
    
                    continue;
                }
                queue.offer(new int[]{
    
    tx,ty});
                visited[tx][ty] = 1;
                res++;
            }
        }

        return res;


    }
}

Four, recursion

Insert picture description here

class Solution {
    
    

    public int dig_num(int target){
    
    
        int sum = 0;
        while(target>0){
    
    
            sum+=target%10;
            target/=10;
        }

        return sum;
    }

    public int movingCount(int m, int n, int k) {
    
    
        if(k==0){
    
    
            return 1;
        }

        int[][] visited = new int[m][n];
        visited[0][0] = 1;

        int res=1;
        for(int i=0;i<m;i++){
    
    
            for(int j=0;j<n;j++){
    
    
                if(i==0&&j==0||dig_num(i)+dig_num(j)>k){
    
    
                    continue;
                }
                if(i-1>=0){
    
    
                    visited[i][j]|=visited[i-1][j];
                }
                if(j-1>=0){
    
    
                    visited[i][j]|=visited[i][j-1];
                }
                res+=visited[i][j]==1? 1:0;
            }
        }

        return res;
    }
}

Guess you like

Origin blog.csdn.net/Cxf2018/article/details/109586461