7. 深度优先搜索和广度优先搜索

1. 实现和特性

定义
在这里插入图片描述
搜索-遍历

  1. 每个节点要访问且仅访问一次
  2. 对结点的访问顺序
    1. 深度优先(depth first search)
    2. 广度优先(breadth first search)

1.1 深度优先搜索

DFS代码(递归写法)及遍历顺序

在这里插入图片描述

非递归写法

def DFS(self, tree): 

	if tree.root is None: 
		return [] 

	visited, stack = [], [tree.root]

	while stack: 
		node = stack.pop() 
		visited.add(node)

		process (node) 
		nodes = generate_related_nodes(node) 
		stack.push(nodes) 

	# other processing work 
	...

1.2 广度优先搜索(breadth first search)

使用队列

BFS 使用队列实现

在这里插入图片描述

2. 算法题解

1)102. 二叉树的层次遍历

广度优先遍历

  1. 递归:每层的结点返回到一个数组
  2. 迭代:维护一个队列,不同层时先将每层结点放入队列,之后遍历队列
    并按入队顺序出队并赋给node,将node.val添加到当前数组

递归


// @lc code=start
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {

    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        BFS(res, root, 0);
        return res;
    }

    public void BFS(List<List<Integer>> res, TreeNode root, int level) {
        if (root == null) return;
        // 当层数大于二维数组中的数组数时,上一层的结点已经遍历添加完毕,新建一个数组代表下一层
        if (res.size() == level) res.add(new LinkedList());
        res.get(level).add(root.val); // 往当前层对应的数组添加结点val
        BFS(res, root.left, level + 1);
        BFS(res, root.right, level + 1);
    }

迭代

  public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if (root == null) return res;
        Deque<TreeNode> queue = new LinkedList<>();
        queue.add(root);

        while (!queue.isEmpty()) {
            List<Integer> level = new ArrayList<>();
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                level.add(node.val);
                if(node.left != null) queue.add(node.left);
                if(node.right != null) queue.add(node.right);
            }
            res.add(level);
        }
        return res;
    }
}
// @lc code=end

2)433. 最小基因变化

3)[515] 在每个树行中找最大值

广度优先搜索


// @lc code=start
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<Integer> largestValues(TreeNode root) {
        List<Integer> res  = new ArrayList<>();
        BFS(res, root, 0);
        return res;
    }

    public void BFS(List<Integer> res, TreeNode root, int level) {
        if (root == null) return;
        if (res.size() == level) res.add(level, root.val);
        // 每层中每个分支得到的元素比较 进行最大替换
        res.set(level, Math.max(res.get(level), root.val));
        BFS(res, root.left, level + 1);
        BFS(res, root.right, level + 1);
    }
}
// @lc code=end


3)岛屿数量

  1. dfs,遍历二维数组,找单独为1的格子,找到后以1格子为root结点,向下(周围(上下左右))找其他为’1’的格子,没有1结束,继续寻找下一个单独为1的格子,直到二维数组遍历结束
    public void DFS(char[] [] grid, int r, int c) {

        // 终止条件,当周围某个方向的格子为0时结束此层递归
        if (r < 0 || c < 0 || r >= grid.length || c >= grid[0].length || grid[r][c] == '0') return;

        grid[r][c] = '0';  // 将访问过为1的格子标记为0
        // 深度优先搜索周围(上下左右)的格子
        DFS(grid, r - 1, c);
        DFS(grid, r + 1, c);
        DFS(grid, r, c - 1);
        DFS(grid, r, c + 1);
    }


    public int numIslands(char[][] grid) {
        if (grid == null || grid.length == 0) return 0;

        // 网格高宽
        int nr = grid.length;
        int nc = grid[0].length;
        int num_isLands = 0; // 岛屿数量

        // 递归入口,遍历网格出现1时,进入递归,将其周围为1的格子标记为0
        for (int r = 0; r < nr; ++r) {
            for (int c = 0; c < nc; ++c) {
                if (grid[r][c] == '1') {
                    ++num_isLands;
                    DFS(grid, r, c);
                }
                
            }
        }
        return num_isLands;
    }
发布了90 篇原创文章 · 获赞 4 · 访问量 1432

猜你喜欢

转载自blog.csdn.net/weixin_44145258/article/details/103738352