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

首先假设传进来一个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());

}

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

相关推荐
GetcharZp14 小时前
抛弃低效SSH!这套Ansible+Web可视化神器,让你天天准点下班!
后端
weixin_4462608518 小时前
HACO:面向动态部署环境的对冲式智能计算可靠多智能体调度框架
后端·python·flask
ttwuai19 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
用户83562907805119 小时前
Python 实现 Excel 页面布局与打印设置自动化
后端·python
用户99314415798419 小时前
微服务框架中获取用户信息
后端
xuanWb19 小时前
手写一个 LLM API 网关:Anthropic 与 OpenAI 协议转换的完整实现
后端
苍何19 小时前
给 Codex 换皮肤这门生意,被我开源了
后端
用户83562907805119 小时前
Python 实现 Excel 命名范围(Named Range)的创建与管理
后端·python
程序员David19 小时前
我让 Claude 从架构文档一路干到代码,踩了三个坑才摸清边界
后端