Skip to the content.

leetcode [1104] 二叉树寻路


Contact me:

Blog -> https://cugtyt.github.io/blog/index
Email -> cugtyt@qq.com
GitHub -> Cugtyt@GitHub


在一棵无限的二叉树上,每个节点都有两个子节点,树中的节点 逐行 依次按 “之” 字形进行标记。

如下图所示,在奇数行(即,第一行、第三行、第五行……)中,按从左到右的顺序进行标记;

而偶数行(即,第二行、第四行、第六行……)中,按从右到左的顺序进行标记。

给你树上某一个节点的标号 label,请你返回从根节点到该标号为 label 节点的路径,该路径是由途经的节点标号所组成的。

示例 1:

输入:label = 14
输出:[1,3,4,14]

示例 2:

输入:label = 26
输出:[1,2,6,10,26]

提示:

1 <= label <= 10^6

粗暴方法构建树

class Solution:
    def pathInZigZagTree(self, label: int) -> List[int]:
        level_order = []
        level = 1
        start = 1
        while True:
            tmp = [i for i in range(2**(level - 1), 2**level)]
            if level % 2: tmp = tmp[::-1]
            level_order.append(tmp)
            if label in tmp:
                break
            level += 1
        index = level_order[-1].index(label)
        
        ans = [label]
        for i in range(len(level_order) - 2, -1, -1):
            ans.append(level_order[i][index // 2])
            index //= 2
        return ans[::-1]

来自题解,结合特点数学运算:

因为以1为根节点层次编号的满二叉树可以对应到位的表示,所以用位运算的思路即可。

因为每层的顺序在变,所以每次需要对首位外的其它位取反。

举例14=1110b,

先将14右移,变为111b,然后对除第一位外所有位取反变为100b,即它的根节点4,

同理100b,右移变为10b,对除第一位外所有位取反变为11b,即它的根节点3

一直到1结束。

class Solution:
    def pathInZigZagTree(self, label: int) -> List[int]:
        res = []
        while label != 1:
            res.append(label)
            label >>= 1
            # 这里我采用异或实现
            label = label ^(1 << (label.bit_length() - 1)) - 1
        return [1]+res[::-1]