Algorithm template - DFS and BFS

DFS

The basic idea of ​​depth-first search is to start from a node and traverse the reachable nodes until the traversed nodes have no reachable and untraversable nodes. At this time, return to the previous node and continue to traverse the reachable nodes of the previous node . Arrived nodes that have not yet been traversed until all connected nodes have been visited.

Code

Recursive DFS is easier to understand:

    public void DFS(char[][] board, char[] chs, int x, int y, boolean[][] visited) {
    
    
		// 控制边界
        if (x < 0 || y < 0 || x >= board.length || y >= board[0].length) return false;
        // 如果已经遍历过了,那么就不用在遍历了
        if (visited[x][y]) {
    
    
            return false;
        }
        // 修改变量
        visited[x][y] = true;
		// 下面可以写你的处理逻辑
        ....
		// 搜索四个方向
        DFS(board, chs, idx+1, x-1, y, visited);
        DFS(board, chs, idx+1, x+1, y, visited);
        DFS(board, chs, idx+1, x, y-1, visited);
        DFS(board, chs, idx+1, x, y+1, visited);       
        // 回溯的逻辑 比如 visited[x][y] = false;
        ...
        return res;
    }

Recommendations

  1. First of all, DFS is a very flexible algorithm. The difficulty lies not in writing the code itself, but in how to convert the problem into a DFS solution;
  2. The above template is just a DFS search starting from a starting point. If you want to search all, you can start from each position;
  3. When designing the DFS algorithm, you need to consider:
    1. DFS parameters (basic parameters + parameters needed in the problem);
    2. End condition of DFS recursion (basic condition + condition involved in the problem);
    3. Consideration of the return value of DFS;
    4. Whether backtracking (such as restoring state variables) is required after DFS ends.

BFS

Breadth-first search is the same, except that it starts from a node, visits all its reachable nodes, and then selects a node from its reachable nodes to visit until all nodes are visited.

Code

    public int orangesRotting(int[][] grid) {
    
    
        if (grid.length == 0) {
    
    
        	return 0;
        }
        Deque<int[]> queue = new ArrayDeque();
        // 建立初始状态
        for (int i = 0; i < grid.length; i++) {
    
    
            for (int j = 0; j < grid[0].length; j++) {
    
    
                if (满足条件) {
    
    
                	queue.offer(new int[] {
    
    i,j});
                }
            }
        }
        // 开始BFS
        int[] dx = new int[] {
    
    -1, 1, 0, 0}, dy = new int[] {
    
    0, 0, -1, 1};
        while (!queue.isEmpty()) {
    
    
            int[] point = queue.poll();
            int x = point[0], y = point[1];
            for (int i = 0; i < 4; i++) {
    
    
                int newX = x + dx[i];
                int newY = y + dy[i];
                if (newX >= 0 && newX < m && newY >= 0 && newY < n 
                        && 问题的条件) {
    
    
                    // 下标入队列
                    queue.offer(new int[] {
    
    newX, newY});
                    // 你的处理逻辑
                }
            }
        }
    }

Recommendations

  1. BFS can be seen as a process of continuous outward diffusion from one point to another;
  2. Using BFS can usually solve the shortest and longest path problem, because BFS can count each round of traversal, and DFS traversal statistics are more troublesome.

Guess you like

Origin blog.csdn.net/qq_38684427/article/details/119392754