满二叉树的性质题--二叉树寻路

Posted C_YCBX Py_YYDS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了满二叉树的性质题--二叉树寻路相关的知识,希望对你有一定的参考价值。

题目

题目解析

我们审题可知,这是一棵编号不正常的满二叉树,而看到满二叉树,我们需要想到这几个性质:

  1. 满二叉树第 i 层的结点数为 2 i − 1 2^{i-1} 2i1个。
  2. 满二叉树从第1层到第 i 层所有的结点数为 2 i − 1 2^{i}-1 2i1 个。
  3. 满二叉树和完全二叉树的编号为 i 的结点,他的父节点是 i / 2 i/2 i/2,子节点是 i ∗ 2 i*2 i2 i ∗ 2 + 1 i*2+1 i2+1。(前提是每层的顺序一致)
  • 回到该题,我们发现,它的编号顺序并不是一致的,而是按照蛇形编号,只要我们所要求的结点的编号在第 i 层,则该层遵循的编号方式一致,很显然它的上一层编号方式就不一样,所以我们可以清楚的知道只要与所求结点所在层数的奇偶性相同则编号方式一致!
  • 回归问题,我们如何让编号不一致的进行正确的修改呢?
    我们根据前两个关于结点的个数性质可知,某层结点的起点和终点编号:(i从1开始)
    起点编号(最小值)为 s t a r t = 2 i − 1 − 1 + 1 start = 2^{i-1}-1+1 start=2i11+1
    终点编号(最大值)为 e n d = 2 i − 1 end = 2^{i}-1 end=2i1

有了这两个信息后有什么用呢?
第一个编号奇偶性信息可以帮助我们跳过不需要修改的路径答案,而第二个该层的起点和终点编号则便于我们对原本的编号进行反转为什么要反转?我们观察题目的蛇形编号发现,不过就是在原来的编号顺序下进行反转编号,假如某个结点是该层编号的最大值,而这个最大值的位置经过反转后肯定就是该层的最小值,经过这波折腾,我们可以得出某层编号反转后的编号值公式(假设要改变的编号为 i e n d − i + s t a r t end -i+start endi+start

现在大家的解题思路应该都有了,所以若无必要,建议自己跟着这个思路去码一次,而不是copy代码。

解题代码

class Solution {
public:
    vector<int> pathInZigZagTree(int label) {
        vector <int> ans;
        //先按照既定顺序加入答案
        while(label) {
            ans.emplace_back(label);
            label >>= 1;
        }
        reverse(ans.begin(), ans.end());
//路径中每个结点都表示在这一层中,所以直接遍历ans长度就行
        int start, end, deep = ans.size();
        //ans[deep-1]以及和他相同奇偶的层数不需要修改
        for(int i = 1; i < deep; i++) {
            if((deep & 1) == (i & 1)) continue;     // 判断第 i 层是否需要修改
            start = 1 << (i-1);
            end = 2*start-1;
            ans[i-1] = end - ans[i-1] + start;
        }
        return ans;
    }
};

以上是关于满二叉树的性质题--二叉树寻路的主要内容,如果未能解决你的问题,请参考以下文章

[M二叉树] lc1104. 二叉树寻路(思维+找规律+数学)

力扣1104. 二叉树寻路

高效二叉树寻路算法

二叉树的性质

算法漫游指北(第十三篇):二叉树的基本概念满二叉树完全二叉树二叉树性质二叉搜索树二叉树定义二叉树的广度优先遍历

数学1104. 二叉树寻路(中等)