Java深度优先搜索DFS(含面试大厂题和源码)

news/2024/4/30 5:58:20

深度优先搜索(Depth-First Search,简称DFS)是一种用于遍历或搜索树或图的算法。DFS 通过沿着树的深度来遍历节点,尽可能深地搜索树的分支。当节点v的所在边都已被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这个过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复上述过程,整个过程重复进行,直到所有节点都被访问为止。

深度优先搜索的实现方式:

  1. 递归实现:使用递归函数实现DFS,每次递归调用都访问一个未被访问的相邻节点。
  2. 非递归实现(栈):使用栈来模拟递归过程,每次从栈中取出一个节点,访问其未被访问的相邻节点,并将其压入栈中。

深度优先搜索的应用:

  • 解决迷宫问题:DFS 可以用来找到迷宫的解,通过不断尝试不同的路径直到找到出口。
  • 拓扑排序:在有向无环图(DAG)中,DFS 可以用来进行拓扑排序。
  • 寻找连通分量:在无向图中,DFS 可以用来找到连通分量。
  • 路径查找:在图论中,DFS 可以用来寻找两个节点之间的路径。

深度优先搜索的Java实现(栈):

import java.util.*;public class DepthFirstSearch {private Map<Integer, List<Integer>> graph;private boolean[] visited;public DepthFirstSearch(Map<Integer, List<Integer>> graph) {this.graph = graph;this.visited = new boolean[graph.size()];}public void dfs(int start) {Stack<Integer> stack = new Stack<>();stack.push(start);visited[start] = true;while (!stack.isEmpty()) {int node = stack.pop();System.out.print(node + " ");for (int neighbor : graph.get(node)) {if (!visited[neighbor]) {visited[neighbor] = true;stack.push(neighbor);}}}}public static void main(String[] args) {Map<Integer, List<Integer>> graph = new HashMap<>();graph.put(0, Arrays.asList(1, 2));graph.put(1, Arrays.asList(3));graph.put(2, Arrays.asList(3));graph.put(3, Collections.emptyList());graph.put(4, Arrays.asList(5));graph.put(5, Collections.emptyList());DepthFirstSearch dfs = new DepthFirstSearch(graph);dfs.dfs(0); // 应输出 0 1 3 2}
}

在面试中,深度优先搜索是一个重要的算法问题,它考察应聘者对图的遍历和递归的理解。通过实现深度优先搜索,可以展示你对基本算法和数据结构的掌握程度。希望这些知识点和示例代码能够帮助你更好地准备面试!

题目 1:二叉树的深度

描述
给定一个二叉树,找出其最大深度。

示例

输入: 二叉树3/ \9  20/   \15   7
输出: 3

Java 源码

public class MaxDepth {public int maxDepth(TreeNode root) {if (root == null) {return 0;}return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;}public static void main(String[] args) {MaxDepth solution = new MaxDepth();TreeNode root = new TreeNode(3);root.left = new TreeNode(9);root.right = new TreeNode(20);root.left.right = new TreeNode(15);root.right.left = new TreeNode(7);int result = solution.maxDepth(root);System.out.println("Max depth of binary tree: " + result);}
}class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) { val = x; }
}

题目 2:路径总和

描述
给定一个二叉树和一个目标和,确定所有从根到叶子的路径上总和等于目标和的路径。

示例

输入: 二叉树,sum = 255/ \4   8/   / \11  13  4/  \      \7    2      9
输出: [[5,4,11,7], [5,8,4,4]]

Java 源码

public class PathSum {public List<List<Integer>> pathSum(TreeNode root, int sum) {List<List<Integer>> result = new ArrayList<>();List<Integer> path = new ArrayList<>();dfs(root, sum, path, result);return result;}private void dfs(TreeNode node, int remaining, List<Integer> path, List<List<Integer>> result) {if (node == null) {return;}path.add(node.val);if (node.left == null && node.right == null && remaining == node.val) {result.add(new ArrayList<>(path));}dfs(node.left, remaining - node.val, path, result);dfs(node.right, remaining - node.val, path, result);path.remove(path.size() - 1);}public static void main(String[] args) {PathSum solution = new PathSum();TreeNode root = new TreeNode(5);root.left = new TreeNode(4);root.right = new TreeNode(8);root.left.left = new TreeNode(11);root.left.right = new TreeNode(13);root.right.left = new TreeNode(4);root.right.right = new TreeNode(7);root.left.right.left = new TreeNode(2);root.left.right.right = new TreeNode(9);List<List<Integer>> result = solution.pathSum(root, 25);System.out.println("Path sum: " + result);}
}

题目 3:子图同构

描述
给定两个有向图,判断它们是否是同构的。如果一个图的节点可以一一映射到另一个图的节点,并且映射后的图与原图结构相同,则这两个图是同构的。

示例

输入: 两个图的邻接表表示
图1: [[1,2],[2,3],[3,4]]
图2: [[1,2],[2,3],[3,4]]
输出: true

Java 源码

public class GraphIsomorphism {public boolean isIsomorphic(Map<Integer, List<Integer>> graph1, Map<Integer, List<Integer>> graph2) {if (graph1.size() != graph2.size()) {return false;}Map<Integer, Integer> mapping = new HashMap<>();Queue<Integer> queue = new LinkedList<>();queue.offer(1);mapping.put(1, 1);while (!queue.isEmpty()) {int node1 = queue.poll();int node2 = mapping.get(node1);List<Integer> neighbors1 = graph1.get(node1);List<Integer> neighbors2 = graph2.get(node2);if (!neighbors1.size() == neighbors2.size()) {return false;}for (int i = 0; i < neighbors1.size(); i++) {int neighbor1 = neighbors1.get(i);int neighbor2 = neighbors2.get(i);if (!mapping.containsKey(neighbor1)) {queue.offer(neighbor1);mapping.put(neighbor1, neighbor2);} else if (!mapping.get(neighbor1).equals(neighbor2)) {return false;}}}return true;}public static void main(String[] args) {GraphIsomorphism solution = new GraphIsomorphism();Map<Integer, List<Integer>> graph1 = new HashMap<>();graph1.put(1, Arrays.asList(2));graph1.put(2, Arrays.asList(3));graph1.put(3, Arrays.asList(4));Map<Integer, List<Integer>> graph2 = new HashMap<>();graph2.put(1, Arrays.asList(2));graph2.put(2, Arrays.asList(3));graph2.put(3, Arrays.asList(4));boolean result = solution.isIsomorphic(graph1, graph2);System.out.println("Graphs are isomorphic: " + result);}
}

这些题目和源码展示了深度优先搜索在解决实际问题中的应用。在面试中,能够根据问题的特点选择合适的算法并实现其解决方案是非常重要的。希望这些示例能够帮助你更好地准备面试!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.cpky.cn/p/11772.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

FreeRTOS学习 -- 再识

工作中一直使用FreeRTOS进行着开发&#xff0c;但是没有进行过系统的总结过。现在将快速使用几天时间将FreeRTOS相关知识点加以总结。 官网&#xff1a; https://www.freertos.org/zh-cn-cmn-s/ 参看资料&#xff1a; 正点原子 STM32F1 FreeRTOS开发手册_V1.2.pdf The FreeRTOS…

linuxday05

1、makedile原理&#xff08;增量编译生成代码&#xff09; # &#xff08;注释符&#xff09; 目标------依赖 目标不存在//目标比依赖旧才会执行命令&#xff1b; makefile的实现 1、命名要求&#xff08;Makefile/makefile&#xff09; 2、规则的集合 目标文件&#…

最新在线工具箱网站系统源码

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 系统内置高达72种站长工具、开发工具、娱乐工具等功能。此系统支持本地调用API&#xff0c;同时还自带免费API接口&#xff0c; 是一个多功能性工具程序&#xff0c;支持后台管理、上…

docker进行jenkins接口自动化测试持续集成实战

文章目录 一、接口功能自动化测试项目源码讲解二、接口功能自动化测试运行环境配置1、下载jdk&#xff0c;maven&#xff0c;git&#xff0c;allure并配置对应的环境变量2、使用docker安装jenkins3、配置接口测试的运行时环境选择对应节点4、jenkins下载插件5、jenkins配置环境…

promise.all方式使用

romise.all( ).then( ) 处理多个异步任务&#xff0c;且所有的异步任务都得到结果时的情况。 比如&#xff1a;用户点击按钮&#xff0c;会弹出一个弹出对话框&#xff0c;对话框中有两部分数据呈现&#xff0c;这两部分数据分别是不同的后端接口获取的数据。 弹框弹出后的初…

Vue3学习笔记+报错记录

文章目录 1.创建Vue3.0工程1.1使用vue-cli创建1.2 使用vite创建工程1.3.分析Vue3工程结构 2.常用Composition2.1 拉开序幕的setup2.2 ref函数_处理基本类型2.3 ref函数_处理对象类型2.4 ref函数使用总结 1.创建Vue3.0工程 1.1使用vue-cli创建 查看vue/cli版本&#xff0c;确保…