在一棵无限的二叉树上,每个节点都有两个子节点,树中的节点 逐行 依次按 “之” 字形进行标记。
如下图所示,在奇数行(即,第一行、第三行、第五行……)中,按从左到右的顺序进行标记;
而偶数行(即,第二行、第四行、第六行……)中,按从右到左的顺序进行标记。
给你树上某一个节点的标号 label,请你返回从根节点到该标号为 label 节点的路径,该路径是由途经的节点标号所组成的。
示例 1:
输入:label = 14
输出:[1,3,4,14]
示例 2:
输入:label = 26
输出:[1,2,6,10,26]
提示:
1 <= label <= 10^6
主要的思想是fz()函数的逆转。
//把编号进行逆转,比如fz(14,4) = 8(14的位置对应的反转位置是8),fz(2,2) = 3(2的反转对应的3)
private int fz(int num,int dept){
if(dept == 1)
return num;
double t = Math.pow(2,dept-1) - 1 + Math.pow(2,dept) - 1 - num + 1;
return (int)t;
}
public List<Integer> pathInZigZagTree(int label) {
int i = 0;
while((Math.pow(2,i) - 1) < label){
i++;
}
List<Integer> res = new LinkedList<>();
for(int j = i;j > 0;j--){
//注意这里
res.add(0,label);
//如果是奇数行的话
if(j % 2 == 1){
//从左到右的顺序,所以直接求他的父节点即可
label /= 2;
//此时父节点所在的位置是偶数行,顺序应该是从右到左,所以调用函数进行逆转并赋值给label
label = fz(label,j-1);
}else{
//从右到左的顺序,所以先调用函数进行逆转,即变回从左到右顺序的编号
label = fz(label,j);
//这是他的父节点,此时父节点在奇数行,不需要进行反转
label /= 2;
}
}
return res;
}