二叉树寻路
题目描述:
在一棵无限的二叉树上,每个结点都有两个子结点,树中的结点逐行依次按“之”字形进行标记。
如下图所示,在奇数行(即,第一行、第三行、第五行......)中,按从左到右的顺序进行标记;
而偶数行(即,第二行、第四行、第六行......)中,按从右到左的顺序进行标记。
给你树上某一个结点的标号label,请你返回从根结点到该标号为label结点的路径,该路径是由途径的结点标号所组成的。
示例1:
输入:label = 14
输出:[1, 3, 4, 14]
示例2:
输入:label = 26
输出:[1, 2, 6, 10, 26]
提示:
- 1 <= label <= 10^6
思路:
如果是一颗正常顺序编号的完全二叉树,父结点的编号为子结点编号//2;依题意,每隔一层会有一次反转编号顺序,所以只需要将当前层的编号再反转一次,即可与上一层保持相同顺序,然后根据正常顺序编号的完全二叉树的规律求父结点的编号;在一棵完全二叉树中,根结点层数为0,对于任意一个编号为label的结点,它的层数为log(label, 2)取整,假定该层数为h;在第h层,结点的编号范围[start, end]为[2^h, 2^(h+1)-1],则编号i反转后的编号为start + end - i;从label结点开始逐层向上计算其父结点编号,最后一个结点必然是根结点,编号为1,最后按添加结点顺序反转即可得到根结点到label结点的路径。
python代码:
class Solution:
def pathInZigZagTree(self, label: int) -> List[int]:
def reverse_level(i, h):
return pow(2, h) + (pow(2, h+1) - 1 - i)
h = int(log(label, 2))
ans = [label]
while label != 1:
label = reverse_level(label, h) // 2
ans.append(label)
h -= 1
ans.reverse()
return ans