难度中等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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。