一、题目
在一棵无限的二叉树上,每个节点都有两个子节点,树中的节点 逐行 依次按 “之” 字形进行标记。
如下图所示,在奇数行(即,第一行、第三行、第五行……)中,按从左到右的顺序进行标记;
而偶数行(即,第二行、第四行、第六行……)中,按从右到左的顺序进行标记。
给你树上某一个节点的标号 label,请你返回从根节点到该标号为 label 节点的路径,该路径是由途经的节点标号所组成的。
点击查看原题
难度级别: 中等
二、思路
1)数学方法
树为满二叉树的情况下,可以根据孩子节点确定父节点,如孩子节点为16
,父节点为val=16/2=8
,可本题中节点按照“之”字形标记,父节点需要根据计算更改,假设每层节点最大值为right
,最小值为left
,则“之”字形标记的父节点值为right - (val - left)
,代码中的right
是每层最大值+1
,所以为right - 1 - (val - left)
三、代码
1)数学方法
class Solution {
public List<Integer> pathInZigZagTree(int label) {
List<Integer> ans = new ArrayList();
int right = 1;
while (right <= label) { // 找到label所在的层最大值+1
right = right << 1;
}
right = right >> 1; // 移动right到父节点层的最大值+1
while (label != 0) {
ans.add(label); // 记录查找路径
label = label >> 1; // 求父节点
int left = right >> 1;
label = right - 1 - (label - left); // 重新标记父节点所在的位置
right = right >> 1;
}
Collections.reverse(ans);
return ans;
}
}
时间复杂度为O(logn)
,空间复杂度为O(logn)