C++ 寻找公共祖先LCA解决《T206.小R的二叉树探索》| 豆包MarsCode AI刷题

53 阅读3分钟

题目内容与要求

在一个神奇的二叉树中,结构非常独特:

  • 每层的节点值赋值方向是交替的,第一层从左到右,第二层从右到左,以此类推。
  • 该二叉树有无穷多层。

小R对这个二叉树充满了好奇,他想知道,在二叉树中两个节点之间 xy 的路径长度是多少。

思路解析

1. 确定节点位置

首先,我们需要确定给定节点值 xy 在二叉树中的位置。这包括节点所在的层级和该层中的位置。

2. 计算路径长度

接下来,我们需要计算两个节点之间的路径长度。这可以通过找到两个节点的最近公共祖先(LCA)来实现。路径长度等于从每个节点到LCA的距离之和。

代码解释

1. NodePosition 结构体

struct NodePosition {
    int level; // 层级
    int index; // 在该层中的位置
};

这个结构体用于存储节点的位置信息,包括节点所在的层级和该层中的位置。

2. findPosition 函数

NodePosition findPosition(int nodeValue)
{
    int level = 0;
    int index = 0;
    int currentLevelNodes = 1;
    int totalNodes = 0;

    while (nodeValue > totalNodes + currentLevelNodes)
    {
        totalNodes += currentLevelNodes;
        currentLevelNodes *= 2;
        level++;
    }

    int remainingNodes = nodeValue - totalNodes - 1;
    index = (level % 2 == 0) ? remainingNodes : currentLevelNodes - 1 - remainingNodes;

    return {level, index};
}
  • 功能:计算给定节点值在树中的位置。
  • 步骤
    1. 初始化层级 level、索引 index、当前层节点数 currentLevelNodes 和总节点数 totalNodes
    2. 使用 while 循环确定节点所在的层级。
    3. 计算剩余节点数 remainingNodes
    4. 根据层级的奇偶性确定节点在该层中的位置。

3. solution 函数

int solution(int x, int y)
{
    NodePosition x_pos = findPosition(x);
    NodePosition y_pos = findPosition(y);

    int x_level = x_pos.level;
    int y_level = y_pos.level;

    // 计算公共祖先(LCA)
    int lca_level = max(x_pos.level, y_pos.level);

    while (x_pos.level != y_pos.level)
    {
        if (x_pos.level > y_pos.level)
        {
            x_pos.level--;
            x_pos.index /= 2;
            lca_level--;
        }
        else
        {
            y_pos.level--;
            y_pos.index /= 2;
            lca_level--;
        }
    }

    while (x_pos.index != y_pos.index)
    {
        x_pos.index /= 2;
        y_pos.index /= 2;
        lca_level--;
    }

    return (x_level - lca_level) + (y_level - lca_level);
}
  • 功能:计算两个节点之间的路径长度。
  • 步骤
    1. 调用 findPosition 函数获取两个节点的位置。
    2. 初始化最近公共祖先(LCA)的层级 lca_level
    3. 使用 while 循环调整两个节点的层级,直到它们在同一层级。
    4. 使用 while 循环调整两个节点的索引,直到它们在同一位置。
    5. 返回路径长度,即 x_level - lca_level + y_level - lca_level

核心知识

1. 二叉树的层次结构

二叉树是一种数据结构,其中每个节点最多有两个子节点。在这个特殊结构的二叉树中,每层节点值的赋值方向是交替的。

2. 最近公共祖先(LCA)

最近公共祖先(Lowest Common Ancestor, LCA)是指两个节点在树中的公共祖先中层级最低的一个。计算LCA是解决许多树形结构问题的关键步骤。

3. 二叉树节点位置计算

通过层级和索引计算节点位置是解决此类问题的基础。层级表示节点所在的层次,索引表示节点在该层中的位置。

总结

代码通过以下步骤解决了计算二叉树中两个节点之间路径长度的问题:

  1. 确定节点位置:使用 findPosition 函数计算节点在二叉树中的位置。
  2. 计算路径长度:通过找到两个节点的最近公共祖先(LCA)来计算路径长度。

具体步骤包括:

  • 使用 findPosition 函数确定节点的位置。
  • 通过调整节点的层级和索引来找到LCA。
  • 计算路径长度为从每个节点到LCA的距离之和。

以后遇到相似题型我们可以用此方法来求解。