在一棵无限的二叉树上,每个节点都有两个子节点,树中的节点 逐行 依次按 “之” 字形进行标记。
如下图所示,在奇数行(即,第一行、第三行、第五行……)中,按从左到右的顺序进行标记;
而偶数行(即,第二行、第四行、第六行……)中,按从右到左的顺序进行标记。
给你树上某一个节点的标号 label
,请你返回从根节点到该标号为 label
节点的路径,该路径是由途经的节点标号所组成的。
示例 1:
输入:label = 14 输出:[1,3,4,14]
示例 2:
输入:label = 26 输出:[1,2,6,10,26]
提示:
1 <= label <= 10^6
思路:
首先找到label是在第几层,
然后因为是完全二叉树,所以每一层开头的节点的label是已知的,第n层对应的节点下标从2 ** (n - 1)到 2**(n) - 1,
所以可以知道label在其所在层的下标,然后经过一番计算,
也可以得到label的父节点在其所在层的下标,就这样一层层地往上找至根节点即可。
class Solution(object):
def pathInZigZagTree(self, label):
"""
:type label: int
:rtype: List[int]
"""
def findLayer(target, root_val, layer): #找某个label是在第几层
if root_val + 2 ** (layer) < target:
return findLayer(target, root_val + 2 ** (layer), layer + 1)
else:
return layer + 1
layer = findLayer(label, 1, 1)
res = []
while label > 1:
for i in range(2 ** (layer - 1), 2 **(layer)):
if i == label:#在当前层找到了label
idx = i - 2 ** (layer - 1) #label在本层的下标
parentidx = (2 ** (layer - 1) - 1 - idx )// 2 #label的父节点在上一层的下标
# print cnt, parentcnt
break
res = [label] + res
label = [i for i in range(2 ** (layer - 2), 2 **(layer - 1))][parentidx]
layer -= 1
return [1] + res