在一棵无限的二叉树上,每个节点都有两个子节点,树中的节点 逐行 依次按 “之” 字形进行标记。
如下图所示,在奇数行(即,第一行、第三行、第五行……)中,按从左到右的顺序进行标记;
而偶数行(即,第二行、第四行、第六行……)中,按从右到左的顺序进行标记。
给你树上某一个节点的标号 label,请你返回从根节点到该标号为 label 节点的路径,该路径是由途经的节点标号所组成的。
示例 1:
代码语言:javascript复制输入:label = 14
输出:[1,3,4,14]
示例 2:
代码语言:javascript复制输入:label = 26
输出:[1,2,6,10,26]
提示:
1 <= label <= 10^6
解题思路
1,没有限制,其实就是一棵完全二叉树
2,完全二叉树的性质:
正常得满二叉树编码方式,根节点index是1,那假设父节点index是n,那左子树节点是2 * n, 右子树 2 * n 1
3,在不zigzag 的基础上给二叉树编号,我们可以很容易得到路径。label/2 直到根节点
4,考虑zigzag,分两种情况
A,label 在偶数层,这种不需要处理
B,label在奇数层,需要在当前层做镜像处理。
5,等到原始路径后,除了根和最后一层,中间层分两种情况。
A,label 在偶数层,这种不需要处理
B,label在奇数层,需要在当前层做镜像处理。
代码实现
代码语言:javascript复制func pathInZigZagTree(label int) []int {
var path []int
h:=height(label)
rl:=label
if h%2==1{
row:=getRow(h)
index:=0
for i:=0;i<len(row);i {
if row[i]==label{
index=i
break
}
}
rl=row[len(row)-1-index]
}
for rl>0{
path=append([]int{rl},path...)
rl/=2
}
path[len(path)-1]=label
//fmt.Println(path)
for i:=1;i<len(path)-1;i {
index:=0
row:=getRow(i)
for k:=0;k<len(row);k {
if row[k]==path[i]{
index=k
break
}
}
if i%2==1{
path[i]=row[len(row)-1-index]
fmt.Println(index,row,path[i],i,len(row)-1-index)
}
}
return path
}
func pow(x,y int)int{
z:=1
for i:=0;i<y;i {
z*=x
}
return z
}
func height(x int)int{
i:=0
for x>0{
i
x/=2
}
return i-1
}
func getRow(i int)[]int{
var row []int
for j:=pow(2,i);j<pow(2,i 1);j {
row=append(row,j)
}
//fmt.Println(row)
return row
}