Interview Question 13: The range of motion of the robot (C ++)

Title address: https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/

Title description

There is a grid with m rows and n columns on the ground, from coordinate [0,0] to coordinate [m-1, n-1]. A robot starts from the grid of coordinates [0, 0], it can move one grid to the left, right, up, and down at a time (it cannot move outside the grid), nor can it enter the row and column coordinates. The sum of the digits is greater than k's 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 the square [35, 38] because 3 + 5 + 3 + 8 = 19. How many grids can the robot reach?

Example questions

Example 1:

Input: m = 2, n = 3, k = 1
Output: 3
Example 2:

Input: m = 3, n = 1, k = 0
Output: 1
Tip:

1 <= n,m <= 100
0 <= k <= 20

Problem-solving ideas

The matrix search problem can be solved by breadth-first search or depth-first search strategy, because it is from the upper left corner to the lower right corner, so it can be reached only by going down and right, without going up and left.

The range of motion of the robot needs to meet the following two conditions at the same time:

  • The sum of the current grid coordinate digits is less than or equal to k;
  • Starting from coordinates (0, 0), the current grid can be reached by moving up, down, left, and right.

BFS: Breadth-first search uses a queue to solve the problem. We put each point that has not been searched into the queue at once, and then pops the head element of the queue as the currently traversed node. BFS is here, if you do not need to determine the specific number of traversal to the current, the template is as follows

while (queue queue is not empty) 
    cur = queue.pop ()
     for all adjacent nodes of node in cur:
         if the node is valid and has not been visited: 
            queue.push (the node)

If you need to determine which layer is currently traversed, that is, the number of steps or the level of the binary tree, the template is as follows

Level level = 0 
while (queue queue is not empty) the 
    number of elements in the queue size = queue.size () // The number of nodes that need to move forward 
    while ( size- ) { 
        cur = queue.pop ()
         for All adjacent nodes of node in cur:
             if the node is valid and has not been visited: 
                queue.push (the node) 
    } 
layer level ++;

In this problem, we don't need to record the number of traversal layers, we only need to count how many points are traversed. We use visited to record whether a point has been traversed.

DFS:深度优先搜索通过递归,先朝着一个方向搜索到底,再回溯至上个节点,沿另一个方向搜索,依次类推。在本题中,我们用数组visited来存储每个元素是否已被访问,一般的时候,我们是从上下左右四个方向行走,但分析本题可发现,从下和右两个方向前行,所以,我们最后使用dfs(x + 1, y, m, n, k) + dfs(x, y + 1, m, n, k) + 1来返回向下和向右走的数目。需要注意的一点是剪枝条件,在搜索中,遇到数位和超出目标值、此元素已访问,则应立即返回,即可行性剪枝。这里我们剪枝的条件设置为当前节点已被访问或该元素下标溢出,以及行坐标x和列坐标y的数位和(即个位+十位)大于k。

程序源码

BFS

class Solution {
public:
    int visited[100][100];
    int step = 0; 
    int movingCount(int m, int n, int k) {
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                visited[i][j] = 0; //初始化,所有元素均未访问
            }
        }
        queue<pair<int,int>> que;
        que.push({0, 0});
        visited[0][0] = 1; //已访问
        int dir_x[] = {0, 0, -1, 1};  //x方向坐标
    int dir_y[] = {-1, 1, 0, 0};  //y方向坐标
        while(!que.empty())
        {
            auto front = que.front();
            que.pop();
            int x = front.first;
            int y = front.second;
            step++;
            for(int i = 0; i < 4; i++)
            {
                int new_x = x + dir_x[i];
                int new_y = y + dir_y[i];
                if(new_x < 0 || new_y < 0 || visited[new_x][new_y] == 1 || new_x >= m || new_y >= n || (new_x / 10 % 10 + new_x % 10 + new_y / 10 % 10 + new_y % 10) > k) continue;
                que.push({new_x, new_y});
                visited[new_x][new_y] = 1;
            }
        }
        return step;
    }
};

DFS

class Solution {
public:
    int visited[100][100];
    int step = 0; 
    int movingCount(int m, int n, int k) {
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                visited[i][j] = 0; //未访问
            }
        }
        return dfs(0, 0, m, n, k);
    }
    int dfs(int x, int y, int m, int n, int k)
    {
        if(visited[x][y] == 1 || x >= m || y >= n || (x / 10 % 10 + x % 10 + y / 10 % 10 + y % 10) > k) return 0;
        visited[x][y] = 1; //已访问
        step = dfs(x + 1, y, m, n, k) + dfs(x, y + 1, m, n, k) + 1;
        return step;
    }
};

参考文章

https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/c-shi-xian-dfs-he-bfs-by-yun-wang-gui/

Guess you like

Origin www.cnblogs.com/wzw0625/p/12731031.html