[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. 二叉树寻路(思维+找规律+数学)的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 1104. 二叉树寻路/103. 二叉树的锯齿形层序遍历/ 171. Excel表列序号/ 987. 二叉树的垂序遍历