LeetCode解题分享:1104. Path In Zigzag Labelled Binary Tree

Problem

In an infinite binary tree where every node has two children, the nodes are labelled in row order.

In the odd numbered rows (ie., the first, third, fifth,…), the labelling is left to right, while in the even numbered rows (second, fourth, sixth,…), the labelling is right to left.

在这里插入图片描述

Given the label of a node in this tree, return the labels in the path from the root of the tree to the node with that label.

Example 1:

Input: label = 14
Output: [1,3,4,14]

Example 2:

Input: label = 26
Output: [1,2,6,10,26]

Constraints:

1 <= label <= 10^6

解题思路

   这一题看上去我们可以将需要的树先建立起来,在去寻找节点即可,事实上,在寻找节点的过程中依然不是那么方便,重点在于每隔一层都会被翻转一次。而且题目给出的条件是有近 1 0 6 10^6 106个节点,建立这么庞大的树,内存会有比较大的浪费,因此我们必须从纯数学的角度来求解这一题。

   我们先立下规定,我们将根节点记为第0层,根节点的两个节点记为第1层,以此类推,不难发现,第 i i i层的数据的范围是 [ 2 i , 2 i + 1 − 1 ] [2^i, 2^{i+ 1}-1] [2i,2i+11],两边可以取得到。而且可以发现,奇数层的数据被反转,而偶数层的数据并没有被反转。

   假设我们的数据 n n n处在偶数层,可以知道,我们所在的这一层没有反转,如果它的上一层没有被反转的话,我们可以很容易求出它的父节点是 n / / 2 n // 2 n//2,双斜杠表示的是整除。但是上一层进行了反转, n n n的父节点发生了改变,此时上一层的最右端是该层的最小值,最左端是该层的最大值,考虑到每一层内部仅仅是方向改变了,因此,未经过反转的父节点和经过反转的父节点在位置上是对称的,即未经反转的父节点到最小值的距离和经过反转的父节点到最大值的距离是相同的。利用这一条件既可以根据未经反转的父节点求出经过反转之后的实际的父节点。

   同理,当我们的数据 n n n处于奇数层时,我们必须根据上面的条件先求出上一层的父节点实际对应的子节点,道理依然是当前节点和该层最小值之间的距离和实际的当前节点和该层最大值之间的距离是相同的。

   代码如下:先将当前的节点保存起来,再根据节点的数据来计算当前数据树第几层,再去根据层数取选择对应的计算过程,一直到节点数据为1。

class Solution:
    def pathInZigZagTree(self, label: int) -> List[int]:
        seq = []
        n = label
        while n != 1:
            seq.append(n)
            level = math.floor(math.log2(n))
            if level % 2 == 0:
                n = n // 2
                n = 2 ** (level - 1) + (2 ** (level) - 1 - n)

            if level % 2 == 1:
                n = 2 ** level + (2 ** (level + 1) - 1 - n)
                n = n // 2

        seq.append(1)
        return seq[::-1]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值