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

Posted Ypuyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[M二叉树] lc1104. 二叉树寻路(思维+找规律+数学)相关的知识,希望对你有一定的参考价值。

1. 题目来源

链接:1104. 二叉树寻路

2. 题目解析

纯找规律的一道题目。

树是一颗满二叉树,也是完全二叉树。子节点找父节点就是 x/2。在不考虑偶数层反转的情况下,直接一路 x/2 就能找到父节点路径。按照该思想考虑,不难发现规律如下:

  • 偶数层只是将原来编号的顺序颠倒过来了,那么只需要将其进行 对称 的恢复即可。
  • 每一层中,对称的两点的和是一样的。 故可以预处理每一层的和,找对称编号时,只需用和减去当前点即可。
  • label 编号是不变的,不能因为 label 编号在偶数层,就将其改变为对称点。
  • 所以,当 labe 在偶数层时,它的父节点在奇数层,此时,所有是奇数层节点需要进行对称改变,偶数层不变。 同理,当 labe 在奇数层时,它的父节点在偶数层,此时,所有是偶数层节点需要进行对称改变,奇数层不变。

突然想到一个绝妙的方法:

也可以这样理解,本题其实反转奇数行,或者反转偶数行,得到的答案都是一样的。 如果 label 在奇数行,说明该行不反转,那么就将所有的偶数行反转即可,答案是一致的。


  • 时间复杂度 O ( l o g n ) O(logn) O(logn)
  • 空间复杂度 O ( l o g n ) O(logn) O(logn)

代码:

找规律,建议看看题解中的图。

class Solution {
public:
    vector<int> pathInZigZagTree(int label) {
        vector<int> init;
        init.push_back(1);
        int L = 1, R = 1;
        for (int i = 0; i < 20; i ++ ) {    // L+R=3145727
            L = L * 2;
            R = R * 2 + 1;
            init.push_back(L + R);
        }

        vector<int> res;
        while (label) res.push_back(label), label >>= 1;
        reverse(res.begin(), res.end());
        // res.size() 代表label所在的层数
        // 如果res在偶数层,则意味着奇数层的需要对称改变,0,2,4
        // 如果res在奇数层,则意味着偶数层的需要对称改变,1,3,5
        for (int i = 1; i < res.size(); i ++ ) {                // 从0开始有个小bug,需要再判断,从1开始即可
            if ((res.size() & 1) != (i & 1)) continue;
            res[i] = init[i] - res[i];
        }

        return res;
    }
};

以上是关于[M二叉树] lc1104. 二叉树寻路(思维+找规律+数学)的主要内容,如果未能解决你的问题,请参考以下文章

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

1104. 二叉树寻路

1104. 二叉树寻路

LeetCode 1104. 二叉树寻路/103. 二叉树的锯齿形层序遍历/ 171. Excel表列序号/ 987. 二叉树的垂序遍历

LeetCode 1104 二叉树寻路[数学 二叉树 位运算] HERODING的LeetCode之路

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