Share two common search algorithms: BFS and DFS

Posted by Roble on Mon, 28 Feb 2022 02:19:13 +0100

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.
  1. Give priority to finding all adjacent positions of a node
  2. Then take out an adjacent location, such as b, and find all its adjacent locations
  3. Take out the next adjacent position of node A and repeat step 2 until the adjacent positions of node a have performed the operation
  4. Take out b and repeat steps 1, 2 and 3
  • b.
  1. Give priority to finding the adjacent position of node a, such as node b
  2. Find the adjacent position c of b
  3. 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:

  1. The closer to the root node, the earlier the node will traverse
  2. 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
  3. 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

  1. Finish a path first until the end
  2. 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

  1. 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 ~

Topics: Algorithm Programmer dfs bfs