一、题目

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

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

而偶数行(即,第二行、第四行、第六行……)中,按从右到左的顺序进行标记。
1104. 二叉树寻路-每日一题 - 图1

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

点击查看原题
难度级别: 中等

二、思路

1)数学方法

树为满二叉树的情况下,可以根据孩子节点确定父节点,如孩子节点为16,父节点为val=16/2=8,可本题中节点按照“之”字形标记,父节点需要根据计算更改,假设每层节点最大值为right,最小值为left,则“之”字形标记的父节点值为right - (val - left),代码中的right是每层最大值+1,所以为right - 1 - (val - left)

三、代码

1)数学方法

  1. class Solution {
  2. public List<Integer> pathInZigZagTree(int label) {
  3. List<Integer> ans = new ArrayList();
  4. int right = 1;
  5. while (right <= label) { // 找到label所在的层最大值+1
  6. right = right << 1;
  7. }
  8. right = right >> 1; // 移动right到父节点层的最大值+1
  9. while (label != 0) {
  10. ans.add(label); // 记录查找路径
  11. label = label >> 1; // 求父节点
  12. int left = right >> 1;
  13. label = right - 1 - (label - left); // 重新标记父节点所在的位置
  14. right = right >> 1;
  15. }
  16. Collections.reverse(ans);
  17. return ans;
  18. }
  19. }

时间复杂度为O(logn),空间复杂度为O(logn)