LeetCode Wide Search Deep Search Topics

1. The largest area of ​​the island (dfs)

Insert picture description here
Insert picture description here
This question is an upgraded version of the number of pieces that can be captured in one step. " Number of pieces that can be captured in one step" is only traversed from one point, and this question uses all points as the starting point to traverse

  • Depth-first traversal, after selecting a point, it will continue to traverse from the top, bottom, left, and right directions until a certain direction hits 0 or crosses the boundary and then returns
  • Set the traversed point to 0, and the point will not be counted repeatedly when traversing recursively later
int visit(vector<vector<int>>& grid, int init_x, int init_y){
    
    
	 //这里判断时要注意,一定先判断是否越界,再判断值是否为0,否则报错看不出来,我就找了好长时间。。。
     if(init_x<0 || init_y<0 ||  init_x > grid.size()-1  || init_y > grid[0].size()-1 || grid[init_x][init_y]==0 ){
    
    
         return 0;
     }
     int count = 1;
     grid[init_x][init_y] = 0;//将当前访问的区域置0
     int x_d[4] = {
    
    0, 0, -1, 1};//这里用数组比用vector快
     int y_d[4] = {
    
    1, -1, 0, 0};
     for(int d = 0; d < 4; d++){
    
    //开始往4个方向遍历,直到碰到0或越界
         count += visit(grid, init_x + x_d[d], init_y + y_d[d]);
     }
     return count;
 }

int maxAreaOfIsland(vector<vector<int>>& grid) {
    
    
    int res = 0;
    for(int i=0; i<grid.size(); i++){
    
    
        for(int j=0; j<grid[0].size(); j++){
    
    
            int temp = visit(grid, i, j);//每个点都作为初始点,开始遍历
            res = max(res , temp);
        }
    }
    return res;
}

Insert picture description here

2. Rotten oranges (bfs)


Insert picture description here
The main idea:

  • Traverse the two-dimensional array and queue the positions of the rotten oranges
  • Constantly take out the oranges from the queue, and test whether there are fresh oranges in the four directions of up, down, left, and right. If there are fresh oranges, they will rot and put them in the queue.
  • Because the oranges in the queue rot and spread out at the same time, we will write down the number of oranges in the queue at this time each time, and use a for loop to process them all at once.

BFS code framework (pseudo code):

while (!queue.empty()){
    
    
	cur_node = queue.front();
	for(node : cur_node的相邻结点){
    
    
		if(node没被访问过){
    
    
			queue.push(node);
		}
	}
}

If we use the above writing to traverse, we cannot distinguish each "layer" in the BFS traversal. This is because, when traversing, the nodes of the first layer have not finished the queue, and the nodes of the second layer have come in. The nodes of the first and second layers in this queue will be close to each other and cannot be distinguished, and therefore the time elapsed by the currently rotten orange cannot be known.

Therefore, we need to modify the code to record the number of nodes in the queue n before the start of each layer traversal, and then process the n nodes of this layer in one go. Then when traversing the next layer, add one to the variable time

class Solution {
    
    
public:
    int orangesRotting(vector<vector<int>>& grid) {
    
    
        int fresh = 0;
        queue<pair<int,int>> roted;
        for(int i=0; i<grid.size(); i++){
    
    
            for(int j=0; j<grid[0].size(); j++){
    
    
                if(grid[i][j] == 1){
    
    
                    fresh++;//记录新鲜橘子数量
                }else if(grid[i][j] == 2){
    
    
                    roted.push(pair<int,int>(i,j));//存放腐烂橘子的坐标
                }
            }
        }

        int x_d[4] = {
    
    1,-1,0,0};
        int y_d[4] = {
    
    0,0,1,-1};
        int time = 0;
        while(!roted.empty()){
    
    
            int n = roted.size();//为方便记下访问的轮数,记下此时队列中的橘子数,一次访问完
            bool isRoted = false;
            for(int i=0; i<n; i++){
    
    //一轮循环访问队列中一个橘子的相邻结点
                int cur_x = roted.front().first;
                int cur_y = roted.front().second;
                roted.pop();
                for(int d=0; d<4; d++){
    
    
                    if(cur_x+x_d[d] >= grid.size() || cur_x+x_d[d] < 0 || cur_y+y_d[d] >= grid[0].size() || cur_y+y_d[d] < 0){
    
    
                     continue;
                     }
                    if(grid[cur_x+x_d[d]][cur_y+y_d[d]] == 1){
    
    //遇到新鲜橘子
                        grid[cur_x+x_d[d]][cur_y+y_d[d]] = 2;
                        roted.push(pair<int,int>(cur_x+x_d[d],cur_y+y_d[d]));
                        fresh--;//新鲜橘子减1
                        isRoted = true;
                    }
                }
            }
            if(isRoted) time++;//本轮有新鲜橘子腐烂
            else break;//本轮没有新鲜橘子腐烂,表示不会再有橘子腐烂了,此时队列也为空,直接跳出
        }
        return fresh == 0 ? time : -1;
    }
};

Insert picture description here

3. Map analysis (bfs)

Insert picture description hereInsert picture description here
Insert picture description here
I personally think that the most important thing to solve this problem is to understand the two descriptions of " Manhattan distance " and " the closest land distance to it is the largest " described in the title.

  • According to the Manhattan distance formula, this distance means that a person can only go up, down, left, and right in the grid (Guangsou can only search for adjacent grids each time, which is the same as the problem of orange rot). The number of times a grid walks to another grid
  • We set off on land and searched for the sea. Each time the searched ocean is set to land and queued, the distance increases by 1. The next time you start searching from the newly entered land to the neighboring node, no new land enters the queue, and you cannot search forward. The distance obtained at this time is the required "maximum distance"

BFS can be regarded as a sequence traversal. Starting from a certain node, BFS first traverses to the node with a distance of 1, and then the node with a distance of 2, 3, 4... Therefore, BFS can be used to find the shortest path problem. The node that BFS searches first must be the closest node. On the contrary, the last node found by BFS is the node with the farthest distance
Insert picture description here

For example

The initial state of the ocean and land is as follows: the
Insert picture description here
search process is as follows:
Insert picture description here
in fact, the idea of ​​this question is changed, it is exactly the same as the orange rot problem, even the code is the same

int maxDistance(vector<vector<int>>& grid) {
    
    
        queue <pair<int, int>> lands;
        for(int i=0; i<grid.size(); i++){
    
    
            for(int j=0; j<grid[0].size(); j++){
    
    
                if(grid[i][j] == 1){
    
    
                    lands.push(pair<int,int>(i,j));//所有陆地入队列,作为第一层结点9
                }
            }
        }
        if(lands.size() == grid.size()*grid[0].size() || lands.size() == 0){
    
    
            return -1;
        }
        int x_d[4] = {
    
    1,-1,0,0};
        int y_d[4] = {
    
    0,0,1,-1};
        int dis = 0;
        
        while(!lands.empty()){
    
    
            bool new_land = false;
            int n = lands.size();
            for(int i=0; i<n; i++){
    
    
                int cur_x = lands.front().first;
                int cur_y = lands.front().second;
                lands.pop();
                for(int d=0; d<4; d++){
    
    
                    int x = cur_x+x_d[d];//此时访问的格子坐标
                    int y = cur_y+y_d[d];
                    if(x<0 || x>=grid.size() || y<0 || y>=grid[0].size() ){
    
    //越界
                        continue;//此方向越界,继续下一次循环
                    }
                    if(grid[x][y] == 0){
    
    //遇到海洋
                        grid[x][y] = 1;
                        lands.push(pair<int,int>(x,y));
                        new_land = true;//表示有新的陆地入队,需要再搜索一轮
                    }
                }
            }
            if(new_land) dis++;
            else break;
        }
        return dis;
    }

Insert picture description here

Guess you like

Origin blog.csdn.net/qq_42500831/article/details/105474126