面试官问我:"如何实现你项目中的这块代码."我说:"看好了."

首先假设传进来一个json结构比如

js 复制代码
   {node1:node2;
    node2:node3;
    node2:node4;
    node3:node5;
    node4;node5;}       

那现在要实现三个功能第一你要解析这个json结构,第二你要解析后来找到json结构的一个头节点,第三你需要找到任意一个节点的后继节点.

那我们现在来思考第一个功能解析,我期望的一个结构是

js 复制代码
{
    node1=[node2],
    node2=[node3, node4],
    node3=[node5],
    node4=[node5],
    node5=[nodeend],
    nodeend=[]
}

他本质上其实是一个邻接表Map<String, List<String>>他非常适合

  • 图遍历
  • 找路径
  • 拓扑排序
  • 检测环
  • 找入度/出度

来我们把具体代码实现一下

js 复制代码
public static Map<String, List<String>> parseGraph(String input) {
    Map<String, List<String>> graph = new HashMap<>();

    // 去掉首尾的 {}
    String content = input.substring(1, input.length() - 1);

    // 按 ; 切分每条边
    String[] relations = content.split(";");
    //form和to节点

    for (String relation : relations) {
        String[] pair = relation.split(":");
        String from = pair[0];
        String to = pair[1];

        // 如果 from 还没在 map 里,先放一个空列表
        if (!graph.containsKey(from)) {
            graph.put(from, new ArrayList<>());
        }
        graph.get(from).add(to);

        // 保证 to 节点也在 map 里
        if (!graph.containsKey(to)) {
            graph.put(to, new ArrayList<>());
        }
    }

    return graph;
}

上面我们对json结构进行了一个解析接下来呢我们来找到他的头节点

头节点是什么

在这张图里,头节点可以理解为:

没有任何前驱节点的节点,也就是入度为 0 的节点。

比如这里:

  • node2node1 指向
  • node3node2 指向
  • node4node2 指向
  • node5node3node4 指向
  • nodeendnode5 指向

只有 node1 没有被任何节点指向,所以它就是头节点。 接下来我们写一下代码

js 复制代码
//找头节点

public static List<String> findHeadNodes(Map<String, List<String>> graph) {
    List<String> result = new ArrayList<>();

    // 记录所有出现过的节点
    Set<String> allNodes = new HashSet<>();

    // 记录"被别人指向过"的节点
    Set<String> pointedNodes = new HashSet<>();

    // 遍历图
    for (String from : graph.keySet()) {
        // 当前 key 本身也是一个节点
        allNodes.add(from);

        // 当前节点的所有后继节点
        List<String> nextNodes = graph.get(from);

        for (String to : nextNodes) {
            // 后继节点也属于图中的节点
            allNodes.add(to);

            // to 被 from 指向过,说明它不是头节点
            pointedNodes.add(to);
        }
    }

    // 如果一个节点从来没有被指向过,那它就是头节点
    for (String node : allNodes) {
        if (!pointedNodes.contains(node)) {
            result.add(node);
        }
    }

    return result;
}

那最后一个问题的就非常简单了找到一个节点的后继节点

js 复制代码
public static List<String> findSuccessors(Map<String, List<String>> graph, String node) {
if (graph == null || node == null) {
return Collections.emptyList();
}
return graph.getOrDefault(node, Collections.emptyList());

}

就这样我们完美的解决了面试官的问题以及类似的问题都可以这样解决

相关推荐
空中海1 小时前
Nacos 2: Spring Boot Demo 实战
java·spring boot·后端
阿丰资源1 小时前
基于Spring Boot的美容院管理系统(附源码+数据库+文档)
数据库·spring boot·后端
TE-茶叶蛋1 小时前
Spring自动配置分析
java·后端·spring
北风toto1 小时前
SpringBoot 获取配置文件值、获取环境变量的方式
java·spring boot·后端
凤山老林1 小时前
Spring Boot 集成国产开源图库 HugeGraph 实现图谱分析的技术方案
spring boot·后端·开源·hugegraph·图谱分析
神奇小汤圆1 小时前
Java基础+SQL基础 → Spring Boot实战
后端
ReSearch1 小时前
如果Go能采用混合模式,确实会比Rust更优秀
后端
user_lwl2 小时前
解决langchain4j+deepseek使用过程中reasoning_contect报错并适配DeepSeekV4
java·后端
贾铭2 小时前
如何实现一个网页版的剪映(五)如何跳转到视频某一帧
前端·后端