This article is shared from Huawei cloud community< Preliminary study on BFS and DFS algorithms >, author: ayin.
This time I share two common search algorithms
1.BFS is breadth first search
2.DFS is depth first search
Number of islands
Given a two-dimensional grid consisting of '1' (land) and '0' (water), calculate the number of islands. An island is surrounded by water, and it is connected by adjacent land in the horizontal or vertical direction. You can assume that all four sides of the mesh are surrounded by water.
- Example 1:
11110 11010 11000 00000
Output: 1
- Example 2:
11000 11000 00100 00011
Output: 3
In fact, it is easy for us to think of a preliminary solution, that is, starting from a certain point of the two-dimensional network, to find the adjacent land around it until all the included points have no adjacent land. Here, it can be considered that an island has been found, and the rest of the islands can be found in the same way. The key problem here is the order of traversing the islands. In fact, it is not difficult to see that there are two orders
- a.
- Give priority to finding all adjacent positions of a node
- Then take out an adjacent location, such as b, and find all its adjacent locations
- Take out the next adjacent position of node A and repeat step 2 until the adjacent positions of node a have performed the operation
- Take out b and repeat steps 1, 2 and 3
- b.
- Give priority to finding the adjacent position of node a, such as node b
- Find the adjacent position c of b
- Until there is no adjacent position, return to the next adjacent position of a and repeat steps 1 and 2
§ Scheme I
We observe the first method:
- The closer to the root node, the earlier the node will traverse
- Think about what storage structure we use to store the location we find: we store the adjacent location of root in the X structure, then take out an adjacent location a of X, find its adjacent location and continue to store it in X, then take out the next location b adjacent to root in X and continue to find its adjacent location and put it in X. Here we find that the order in which we store x is consistent with the order in which we process x to get other data: first in first out (FIFO). It is not difficult to find out that we can use queues to store X
- A method is needed to avoid repeated access to the location that has been found
Now you can try to write the actual program
public int numIslands(char[][] grid) { if (grid.length==0){ return 0; } Queue<Point> queue = new LinkedList<>(); int count =0; for(int y=0;y<grid.length;y++){ for(int x=0;x<grid[0].length;x++){ // Core part if(grid[y][x]=='1'){ queue.offer(new Point(x,y)); while (queue.size() != 0) { Point nowPoint = queue.peek(); List<Point> pointList = getNearPoints(nowPoint, grid); for (Point point : pointList) { queue.offer(point); // Mark locations that have been accessed grid[point.y][point.x] = '2'; System.out.println(point.y * grid[0].length + point.x); } queue.poll(); } count++; } // Core part } }
Through this example, we can further abstract it into an algorithm in graph theory - BFS
You can refer to leetcode's dynamic graph and algorithm template to deepen your impression
§ Scheme II
Similarly, looking at the second method, we find that
- Finish a path first until the end
- We need to trace back to the initial location after the end of a path, that is, the order of storage node location is opposite to that of processing, that is, FIFO. Here we can use recursion or stack.
Try to write the actual program
- recursion
public int numIslands(char[][] grid) { int len = 0; Set <Integer> visited = new HashSet<>(); for (int y = 0; y < grid.length; y++) { for (int x = 0; x < grid[0].length; x++) { Integer node = y * grid[0].length + x; if (!visited.contains(node)&&grid[y][x] == '1') { visited.add(node); DFS3(node, visited, grid); len++; } } } return len; } boolean DFS(Integer cur, Set<Integer> visited,char [][]grid) { for (Integer next : getNearNodes(cur,grid[0].length,grid.length,grid)) { if (!visited.contains(next)) { visited.add(next); System.out.println(next); DFS(next,visited,grid); } } return true; }
2. Stack
boolean DFS3(Integer cur, Set<Integer> visited,char [][]grid){ Stack<Integer> nodeStack = new Stack<>(); nodeStack.push(cur); while(!nodeStack.empty()){ Integer node = nodeStack.peek(); boolean hasNearNode = false; for(Integer next:getNearNodes(node,grid[0].length,grid.length,grid)){ if(!visited.contains(next)){ visited.add(next); nodeStack.push(next); hasNearNode = true; } } // If the current node has no neighbors, remove the top node of the stack if(!hasNearNode){ nodeStack.pop(); } } return true; }
Through this example, we can further abstract it into an algorithm in graph theory - DFS
Refer to leetcode's dynamic graph and template algorithm (recursion and stack) to deepen the impression
Click follow to learn about Huawei cloud's new technology for the first time ~