You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JS递归实现非二叉树的最近公共祖先(LCA)查找

树结构最近公共祖先(LCA)递归实现方案

核心思路

  • 首先提取整棵树的全局最小值、最大值作为待查找的两个目标节点标识
  • LCA判定逻辑:对于任意节点,若两个目标值分别落在该节点的不同子树中,或其中一个目标值属于当前节点本身,且所有下层子节点都不满足该条件,则当前节点就是最近公共祖先
  • 全程仅使用map、reduce、filter等数组方法实现,符合禁用循环、forEach的要求

原有代码问题说明

  • 原有findPath方法仅做了节点value的嵌套收集,未做LCA的匹配判定,返回结果为嵌套数组,不符合需求
  • 未实现递归终止优化,找到LCA后仍会无差别遍历所有节点,性能较差

完整实现代码

const tree = {
children: [ 
    { 
        children: [
            { 
                children: [],
                values: [15.667786122807836]
            }
        ],
        values: [35.77483035532576, 1.056418140526505]
    },
    {
        children: [
            {
                children: [
                    {
                        children: [],
                        values: [67.83058067285563]
                    }
                ],
                values: [98.89823527559626]
            }
        ],
        values: [51.49890385802418, 41.85766285823911]
    },
],
values: [6.852857017193847, 28.110428400306265, 51.385186145220494]};

// 保留原有极值提取逻辑
const min = graph => {
  return Math.min(...graph.values, ...graph.children.map(graphNode => min(graphNode)));
};

const max = graph => {
  return Math.max(...graph.values, ...graph.children.map(graphNode => max(graphNode)));  
};

// 递归查找LCA的核心方法
const findLCA = (node, target1, target2) => {
  // 统计当前节点匹配的目标数量
  const currentMatch = [target1, target2].filter(t => node.values.includes(t)).length;
  // 汇总所有子节点的递归结果
  const childResult = node.children.reduce((res, child) => {
    // 子树已找到LCA则直接返回,跳过剩余节点遍历
    if (res.lca) return res;
    const [childMatch, childLCA] = findLCA(child, target1, target2);
    if (childLCA) return { matchCount: res.matchCount + childMatch, lca: childLCA };
    return { matchCount: res.matchCount + childMatch, lca: null };
  }, { matchCount: 0, lca: null });

  // 子树已找到LCA,向上传递结果
  if (childResult.lca) return [currentMatch + childResult.matchCount, childResult.lca];
  // 当前节点满足LCA条件,向上返回
  if (currentMatch + childResult.matchCount === 2) {
    return [2, node];
  }
  // 未找到LCA,返回当前子树匹配的目标数量
  return [currentMatch + childResult.matchCount, null];
};

const getMinMaxLCA = graph => {
  if (!graph?.children?.length && !graph?.values?.length) return null;
  const minVal = min(graph);
  const maxVal = max(graph);
  const [_, lcaNode] = findLCA(graph, minVal, maxVal);
  // 若需要返回LCA的values数组,修改为 return lcaNode?.values ?? null
  return lcaNode;
}

// 测试调用
console.log(getMinMaxLCA(tree));

逻辑验证

样例树中最小值1.056418140526505落在左子树,最大值98.89823527559626落在右子树,二者的最近公共祖先为根节点,运行代码可验证输出结果正确。


内容的提问来源于stack exchange,提问作者halfdead30

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 12:45:03