Sword finger offer: motion range of JZ66 robot

Posted by rweston002 on Sun, 26 Dec 2021 12:47:12 +0100

describe

There is a grid of rows and cols columns on the ground. The coordinates are from [0,0] to [rows-1,cols-1]. A robot starts to move from the grid with coordinates 0,0. Each time, it can only move one grid in the left, right, upper and lower directions, but it cannot enter the grid where the sum of digits of row coordinates and column coordinates is greater than threshold. For example, when the threshold is 18, the robot can enter the grid [35,37], because 3 + 5 + 3 + 7 = 18. However, it cannot enter the grid [35,38] because 3 + 5 + 3 + 8 = 19. How many grids can the robot reach?

Range:

1 <= rows, cols<= 100;0 <= threshold <= 20

Example

input1: 1,2,3
output1: 3

input2: 0,1,3
output2: 1

input3: 10,1,100
output3: 29
 Note 3:
[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[0,10],[0,11],[0,12],[0,13],[0,14],
[0,15],[0,16],[0,17],[0,18],[0,19],[0,20],[0,21],[0,22],[0,23],[0,24],[0,25],[0,26],[0,27],
[0,28] These 29, the latter[0,29],[0,30]as well as[0,31]Wait, it's unreachable   

input4: 5,10,10
output4: 21

thinking

As can be seen from the title, since the robot can only move 1 grid at a time, and the sum of digits of row and column coordinates is limited, it is necessary to traverse the grid that can be accessed. It is easy to think of two methods: depth first and breadth first.
The time complexity is O(M*N). Considering the extreme situation, each grid is accessed once
The space complexity is O(M*N), and a two-dimensional array needs to be created

1. Depth first (DFS)

The idea of DFS algorithm is to go to the end in one direction. Only when the conditions are not met will it turn back and continue to go to the end. The traversal will end when all accessible grids are accessed. In the topic, the robot can move in four directions, so the main body of DFS algorithm is to go in four directions, and the current grid needs to be marked as accessed, and the exit conditions are divided into several types:
(1) The index of row and column is out of range; the sum of digits of row and column coordinates exceeds the threshold
(2) The current grid has been accessed

——Rough version

In this version, the counted variables are directly set to global and moved in four directions. This method of thinking is simple and crude, and is universal to DFS problems

public class Solution {
    public int count = 0;//Global variable count
    public int movingCount(int threshold, int rows, int cols) {
        boolean[][] arr = new boolean[rows][cols];
        dfs(arr, 0, 0, threshold);
        return count;
    }
    
    //Calculate the sum of digits of a number
    public int getBitCnt(int num){
        int cnt = 0;
        while(num != 0){
            cnt += num % 10;
            num /= 10;
        }
        return cnt;
    }
    
    //Implementation of DFS algorithm
    public void dfs(boolean[][] arr, int row, int col, int th){
        boolean flag = row < 0 || row == arr.length;
        flag = flag || col < 0 || col == arr[0].length;
        flag = flag || getBitCnt(row) + getBitCnt(col) > th;
        flag = flag || arr[row][col] == true;
        if(flag) return;
        arr[row][col] = true;
        count++;
        dfs(arr, row+1, col, th);
        dfs(arr, row-1, col, th);
        dfs(arr, row, col+1, th);
        dfs(arr, row, col-1, th);
    }
}

——Simplified version

Through the analysis of the topic, since the starting point is in the upper left corner (0, 0), the next grid must be right or lower, so the left and upper can not be considered; At the same time, in order to save space, DFS can directly return the count value, which is composed of three parts:
(1) The number of lattices that currently meet the conditions is 1
(2) The grid to the right of the current grid: dfs(arr, row, col+1, th)
(3) The grid below the current grid: dfs(arr, row+1, col, th)

    public int dfs(boolean[][] arr, int row, int col, int th){
        boolean flag = row == arr.length || col == arr[0].length;
        flag = flag || getBitCnt(row) + getBitCnt(col) > th;
        flag = flag || arr[row][col] == true;
        if(flag) return 0;
        arr[row][col] = true;
        return 1 + dfs(arr, row+1, col, th) + dfs(arr, row, col+1, th);
    }

2. Breadth first (BFS)

The idea of BFS algorithm is to access according to the distance. In this problem, first access the nearest circle, and then expand outward until the access of the whole grid is completed. In this algorithm, the first circle is the upper left corner (0, 0), the second circle is the right and bottom, the third circle is the right and bottom of all elements in the second circle, and so on.

In the BFS algorithm, the general implementation method is to use the queue, so as to ensure that after the latest round of access, the elements of this round are marked for access, and all elements of the next round are added to the queue

import java.util.Queue;
import java.util.LinkedList;
public class Solution {
    public int movingCount(int threshold, int rows, int cols) {
        boolean[][] flag = new boolean[rows][cols];//Used to mark whether the grid is accessed
        int cnt = 0;//To count
        Queue<int[]> que = new LinkedList<>();//The queue holds only a circle of elements
        que.add(new int[]{0, 0});//The first circle starts from (0, 0) and there is only one element
        while(!que.isEmpty()){
            int[] e = que.poll();
            int row = e[0], col = e[1];
            if(row == rows || col == cols || getBitCnt(row)+getBitCnt(col) > threshold || flag[row][col] == true)
                continue;
            cnt++;
            flag[row][col] = true;
            //After the first circle pops up, add the second circle: the elements to the right and below it
            que.add(new int[]{row+1, col});
            que.add(new int[]{row, col+1});
        }
        return cnt;
    }
    
    public int getBitCnt(int num){
        int cnt = 0;
        while(num != 0){
            cnt += num % 10;
            num /= 10;
        }
        return cnt;
    }
}

Topics: Java Algorithm queue dfs bfs