leetcode 1104. 二叉树寻路

1104. 二叉树寻路

难度中等153

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

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

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

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= label <= 10^6

思路:

我们先不考虑题目中特殊化的二叉树,先思考如何恢复正常的二叉树的路径

补充知识:
若已知一节点为 ii,则该节点的左孩子节点为 (2 * i)(2∗i),右孩子节点为 (2 * i + 1)(2∗i+1)
且该节点的父节点为 (i \,/\, 2)(i/2)

对于正常的二叉树,已知节点 ii,根据上述知识我们便可以求得其路径:


let list;
while(label) {
    list.push(label);
    label = label >>1;
}
当 label = 14label=14,则 ans =ans= {14, 7, 3, 114,7,3,1}

之后我们需要将 ansans 转化为题目要求的二叉树的路径

令 deepdeep 为深度

观察题目要求的二叉树,其实不难发现:deepdeep 为偶数时和正常的二叉树是对称的,所以我们只需要对 deepdeep 为偶数时进行处理即可

那么我们如何将正常的数转化为我们需要的呢?

补充知识:
二叉树中第 ii 层一共有 2 ^ {(i-1)}2 
(i−1)
  个数,且前 i - 1i−1 层共有 2 ^ {(i-1)} - 12 
(i−1)
 −1 个数
注意: 这里的 ii 从 11 开始,而在代码实现中 ii 从 00 开始

为了和代码一致,下面的推导我们以 i = 0i=0 为第一层

以节点 1010 举例,假设节点 1010 的深度为 ii,节点 1010 对应的是节点 1313,首先我们需要第 ii 层的节点个数以及第 ii 层的第一个节点的编号 ll 和最后一个节点的编号 rr

其实不难发现:

l = 2^i\\ r = 2 * l - 1\\ 13 = r - 10 + l
l=2 
i
 
r=2∗l−1
13=r−10+l

由此我们可以根据节点 1010 求得节点 1313

最后需要注意的是:要对 ansans 进行反转

代码实现:

/**
 * @param {number} label
 * @return {number[]}
 */
var pathInZigZagTree = function(label) {
    let list = [];
    while(label) {
        list.push(label)
        console.log(label)
        label >>= 1;
    } 
    console.log(list)
    let deep = list.length
    list.reverse()
    for(let i = 0; i < list.length; i++) {
        if((deep & 1) !== (i & 1)) {
            continue
        }
        let l = 2 ** i;
        let r = 2 * l - 1;
        list[i] = r - list[i] + l;
    }
    return list
};


具体解释一下代码中的 (deep\; \&\; 1)(deep&1) !=!= (i\; \&\; 1)(i&1)

当 deepdeep 为 偶数 时,只对 奇数深度 进行修改
当 deepdeep 为 奇数 时,只对 偶数深度 进行修改
而 deepdeep 为二叉树的总深度,ii 为当前遍历的深度,我们可以通过 deep\; \&\; 1deep&1 可以判断 deepdeep 的奇偶
如果 (deep\; \&\; 1)(deep&1) !=!= (i\; \&\; 1)(i&1) 说明 deepdeep 和 ii 具有不同的奇偶性,此时需要对第 ii 层进行修改,但由于 i = 0i=0 为第一层,所以此时需要将 ii 理解为 i + 1i+1 才是当前真实的深度,故当 (deep\; \&\; 1)(deep&1) !=!= (i\; \&\; 1)(i&1) 时不需要修改

复杂度分析

时间复杂度:O(\log label)O(loglabel),求二叉树层数需 O(\log label)O(loglabel),ans.size() = \log labelans.size()=loglabel,则反转一次 ansans 需 O(\log label)O(loglabel),遍历一次 ansans 需 O(\log label)O(loglabel),总体为 O(\log label)O(loglabel)

空间复杂度:O(1)O(1),除返回需要的 ansans 外,额外需要的空间为 O(1)O(1)

作者:liang-sheng-19
链接:https://leetcode-cn.com/problems/path-in-zigzag-labelled-binary-tree/solution/1104-er-cha-shu-xun-lu-c-100-jie-fa-wei-p3ik1/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值