BFS
concept
BFS, breadth first search.
Some children asked, "brother, I just want to draw. Can you speak human words?"
That is, we follow this step——
realization
Here we will introduce the queue, because breadth first search and queue are good friends.
What is a queue? It is a first in first out array, which is very similar to the queue in our daily life. When we insert a new number into the queue, it is inserted at the end. When we take out a number, we have to take it from the beginning. Just like the brush, drawing board or paint just bought by children, they have to queue up (assuming there is no online shopping, no bars!).
Supplement -- about using queues in Python
In Python, you can implement queues in the following ways
collections In the bag deque,Corresponding operation pop()Remove from the tail appendleft() Insert from scratch queue In package queue,Corresponding operation put() insert get() take out Direct use list,As long as it is guaranteed that only pop() take out insert(0,) insert Or just use append() insert list[0]also del list[0] take out Both use list The method is different from which is the first and which is the last
Comparison of three methods
The first is the orthodox Python double ended queue. The disadvantage is that the called function is a little complex. It may be wrong if you accidentally write append.
The second kind of function using encapsulation is very direct, and put() and get() are not easy to confuse. But the queue type actually has a deque in it. It feels like taking off your pants and putting X.
The third advantage is that there is no need to switch packages, but the use of logic in functions may cause confusion. Here, the second code is used for the full version, which is easy to understand. The third code is used for the simplified version, which saves the number of lines. The three methods can be replaced with each other according to your preferences without affecting the results at all.
At this time, the child asked, "uncle, why can breadth first search and queue get together?"
analysis
We can use queues to achieve breadth first search.
Let's set up a queue and add the initial point first
Specifies that one coordinate is taken from the queue at a time
Dye this coordinate, and put the neighbors of this coordinate (good neighbors that meet the requirements and do not repeat) into the queue.
When the queue is empty, the dyeing is completed
Because the queue takes out the last one each time and adds the first one each time, it can be imagined that the first one processed each time is the one with the lowest level and closest to the initial point, and then slowly expands, so as to realize breadth first search.
example
subject
There is a picture represented by a two-dimensional integer array. Each integer represents the pixel value of the picture, and the value is between 0 and 65535.
Give you a coordinate (sr, sc) to represent the pixel value (row, column) at the beginning of image rendering and a new color value newColor to color the image again.
In order to complete the coloring work, start from the initial coordinates, record the connected pixels with the same pixel value as the initial coordinates in the upper, lower, left and right directions of the initial coordinates, and then record the qualified pixels in the four directions and their corresponding connected pixels with the same pixel value as the initial coordinates in the four directions,... Repeat the process. Change the color values of all recorded pixels to new color values.
Finally, the color rendered image is returned.
thinking
First, find the initial node and dye it. This initial node is regarded as the first layer.
Find four nodes around the initial node and dye them (only those that meet the conditions can be dyed). These four nodes are regarded as the second layer.
Then find eight nodes around the four nodes and dye them. These eight nodes are regarded as the third layer.
Repeat the past, step by step, until no qualified node can be found.
The idea is well understood, right? It is a process of diffusion from the middle to the outside. But how? Now here is your keyboard. I'm afraid I can't write it yet.
code
class Solution: def floodFill(self, image: List[List[int]], sr: int, sc: int, newColor: int) -> List[List[int]]: if newColor == image[sr][sc]:return image que, old, = [(sr, sc)], image[sr][sc] while que: point = que.pop() image[point[0]][point[1]] = newColor for new_i, new_j in zip((point[0], point[0], point[0] + 1, point[0] - 1), (point[1] + 1, point[1] - 1, point[1], point[1])): if 0 <= new_i < len(image) and 0 <= new_j < len(image[0]) and image[new_i][new_j] == old: que.insert(0,(new_i,new_j)) return image
DFS
concept
DFS, depth first search.
The children scrambled and said, "from your BFS, I really want to guess what DFS is. Is it --"
thinking
First determine the order of four directions, such as up, down, left and right, up, down, left and right
First, find the initial node and dye it.
According to the order of direction, here is up. First dye the point above this point.
Keep going up and up until it does not meet the requirements, then step back and find the lower direction of this point
Repeat this step.
In other words, first finish everything above this point, then finish everything below this point, then the left, and finally the bottom.
It's easy to understand, right? It's a process from the middle to one direction. But how? Now here is your keyboard. I'm afraid I can't write it yet.
realization
Remember the two methods and three implementations of the title?
This is because DFS usually has two implementation methods, one is recursion, and the other is using stack.
Here we will introduce the stack, because depth first search and stack are good friends.
What is a stack? It is a last in first out array, which is very similar to queue jumping in our daily life. When we insert a new number into the stack, it is inserted in the front. When we take out a number, we have to take it from the beginning. It's like a child jumping in line to buy a paintbrush. He doesn't line up and inserts it directly into the first position. The next service is it.
Supplement -- about using stack in Python
Just use list directly and use its two methods
pop() append()
At this time, the child asked, "uncle, why can breadth first search and stack get together?"
We can use the stack to realize depth first search.
analysis
Let's set up a stack and add the initial point first
Specifies that one coordinate is taken from the stack at a time
Dye the coordinate, and put the neighbors in one direction of the coordinate (good neighbors that meet the requirements and do not repeat) on the stack.
When there are no neighbors with compound requirements in this direction, enter the next direction
When the stack is empty, the dyeing is completed
Because the stack takes out the last one every time and adds the last one every time, it can be imagined that the deepest one is processed first and then expanded slowly, so as to realize depth first search.
example
The title is the same as BFS above, so I won't repeat it here
thinking
First determine the order of four directions, such as up, down, left and right, up, down, left and right
First, find the initial node and dye it.
According to the order of direction, here is up. First dye the point above this point.
Keep going up and up until it does not meet the requirements, then step back and find the lower direction of this point
Repeat this step.
In other words, first finish everything above this point, then finish everything below this point, then the left, and finally the bottom.
It's easy to understand, right? It's a process from the middle to one direction. But how? Now here is your keyboard. I'm afraid I can't write it yet.
code
1, Use stack
class Solution: def floodFill(self, image: List[List[int]], sr: int, sc: int, newColor: int) -> List[List[int]]: if newColor == image[sr][sc]: return image stack, old = [(sr, sc)], image[sr][sc] while stack: point = stack.pop() image[point[0]][point[1]] = newColor for new_i, new_j in zip((point[0], point[0], point[0] + 1, point[0] - 1), (point[1] + 1, point[1] - 1, point[1], point[1])): if 0 <= new_i < len(image) and 0 <= new_j < len(image[0]) and image[new_i][new_j] == old: stack.append((new_i, new_j)) return image
2, Use recursion
class Solution: def floodFill(self, image: List[List[int]], sr: int, sc: int, newColor: int) -> List[List[int]]: if image[sr][sc] != newColor: old, image[sr][sc] = image[sr][sc], newColor for i, j in zip((sr, sr+1, sr, sr-1), (sc+1, sc, sc-1, sc)): if 0 <= i < len(image) and 0 <= j < len(image[0]) and image[i][j] == old: self.floodFill(image, i, j, newColor) return image