在一棵无限的二叉树上,每个节点都有两个子节点,树中的节点 逐行 依次按 “之” 字形进行标记。
如下图所示,在奇数行(即,第一行、第三行、第五行……)中,按从左到右的顺序进行标记;
而偶数行(即,第二行、第四行、第六行……)中,按从右到左的顺序进行标记。
给你树上某一个节点的标号 label,请你返回从根节点到该标号为 label 节点的路径,该路径是由途经的节点标号所组成的。
示例 1:
输入:label = 14
输出:[1,3,4,14]
示例 2:
输入:label = 26
输出:[1,2,6,10,26]
提示:
1 <= label <= 10^6
链接:https://leetcode-cn.com/problems/path-in-zigzag-labelled-binary-tree
思路分析:
题意就是在一个偶数行反转的完全二叉树中,找到编号为 label 的节点,然后将根节点到 label 的路径输出。
这道题特点在于需要推一定的式子。范围不是很大,如果懒得思考,可以直接建树找到label节点,然后推上去。不过这里想通过计算的方式解决这道题。
首先,我们需要找到label节点处于第几行。
我们分析可以得到:第 i 行的区间范围是[ 2(i-1), 2i-1]. 可以枚举行一层层找label.
找到 label 所在行后,再分析可得到:
- 先将label输出。
- 将 label 在该行反转一下。 反转公式就是 2(i-1) + 2i-1-label.
- label /= 2得到其父结点。
class Solution {
public:
vector<int> pathInZigZagTree(int label) {
int idx = 0;
for(int i = 1;i <= 100;i++)
{
int s = pow(2,i-1);
int e = pow(2,i)-1;
if(label >= s && label <= e)
{
idx = i;
break;
}
}
vector<int> ans;
while(label)
{
ans.push_back(label);
int s = pow(2,idx-1);
int e = pow(2,idx)-1;
label = s+(e-label);
label /= 2;
idx--;
}
reverse(ans.begin(),ans.end());
return ans;
}
};