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; } }