二叉树题目:二叉树寻路

文章目录

题目

标题和出处

标题:二叉树寻路

出处:1104. 二叉树寻路

难度

5 级

题目描述

要求

在一个无限的二叉树上,每个结点都有两个子结点,结点按行标号。

在奇数行(即,第一行、第三行、第五行......)中,按从左到右的顺序标号。在偶数行(即,第二行、第四行、第六行......)中,按从右到左的顺序标号。

给定树上某一个结点的标号 label \texttt{label} label,返回从根结点到标号为 label \texttt{label} label 的结点的路径,该路径是由途经的结点标号所组成的。

示例

示例 1:

输入: label = 14 \texttt{label = 14} label = 14

输出: [1,3,4,14] \texttt{[1,3,4,14]} [1,3,4,14]

示例 2:

输入: label = 26 \texttt{label = 26} label = 26

输出: [1,2,6,10,26] \texttt{[1,2,6,10,26]} [1,2,6,10,26]

数据范围

  • 1 ≤ label ≤ 10 6 \texttt{1} \le \texttt{label} \le \texttt{10}^\texttt{6} 1≤label≤106

解法

思路和算法

首先考虑一个简单的问题:如果二叉树的每一行都是按从左到右的顺序标号,如何得到从根结点到标号为 label \textit{label} label 的结点的路径。当每一行都按从左到右的顺序标号时,对于标号为 x x x 的结点,其左子结点标号为 2 x 2x 2x,右子结点标号为 2 x + 1 2x + 1 2x+1,如果 x > 1 x > 1 x>1,则其父结点标号为 ⌊ x 2 ⌋ \Big\lfloor \dfrac{x}{2} \Big\rfloor ⌊2x⌋。因此,对于给定的标号 label \textit{label} label,可以利用上述性质得到从该标号结点到根结点的路径,将路径翻转之后即可得到从根结点到该标号结点的路径。

这道题中,二叉树的奇数行按从左到右的顺序标号,二叉树的偶数行按从右到左的顺序标号,因此需要将标号转换之后才能得到结点位置。考虑二叉树的每一行都是按从左到右的顺序标号,将这样的标号称为下标,和题中定义的标号区分。结点的标号与下标之间的关系如下。

  • 奇数行结点的标号与下标相同。

  • 偶数行结点的标号与下标不同,将整行的下标翻转之后即为标号。

这道题规定根结点在第 1 1 1 层,则第 i i i 层有 2 i − 1 2^{i - 1} 2i−1 个结点,结点的标号范围是 [ 2 i − 1 , 2 i − 1 ] [2^{i - 1}, 2^i - 1] [2i−1,2i−1]。当 i i i 是偶数时,第 i i i 行的每个结点的标号与下标之和为 2 i − 1 + 2 i − 1 2^{i - 1} + 2^i - 1 2i−1+2i−1,由此可以得到同一个结点的标号与下标之间的换算关系。

根据层数与结点标号范围的关系可以定位到标号为 label \textit{label} label 的结点所在层,然后计算从标号为 label \textit{label} label 的结点到根结点的路径,最后将路径翻转即可得到从根结点到标号为 label \textit{label} label 的结点的路径。

对于标号为 label \textit{label} label 的结点,如果其所在层是奇数,则结点下标与标号相同,如果其所在层是偶数,则需要根据换算关系得到结点下标。

得到标号为 label \textit{label} label 的结点的下标之后,即可得到路径上的所有结点下标。对于每个结点下标,根据结点所在层的奇偶性和层数计算结点标号,将标号添加到路径中,当到达标号为 1 1 1 的结点即根结点时,得到反向路径,将反向路径翻转即可得到结果路径。

以下用题目中的两个例子说明。

示例 1, label = 14 \textit{label} = 14 label=14。标号为 label \textit{label} label 的结点在第 4 4 4 层,层数是偶数,该结点的下标是 9 9 9。从该结点到根结点的路径上的结点的下标依次是 [ 9 , 4 , 2 , 1 ] [9, 4, 2, 1] [9,4,2,1],标号依次是 [ 14 , 4 , 3 , 1 ] [14, 4, 3, 1] [14,4,3,1],翻转后得到从根结点到标号为 label \textit{label} label 的结点的路径 [ 1 , 3 , 4 , 14 ] [1, 3, 4, 14] [1,3,4,14]。

示例 2, label = 26 \textit{label} = 26 label=26。标号为 label \textit{label} label 的结点在第 5 5 5 层,层数是奇数,该结点的下标是 26 26 26。从该结点到根结点的路径上的结点的下标依次是 [ 26 , 13 , 6 , 3 , 1 ] [26, 13, 6, 3, 1] [26,13,6,3,1],标号依次是 [ 26 , 10 , 6 , 2 , 1 ] [26, 10, 6, 2, 1] [26,10,6,2,1],翻转后得到从根结点到标号为 label \textit{label} label 的结点的路径 [ 1 , 2 , 6 , 10 , 26 ] [1, 2, 6, 10, 26] [1,2,6,10,26]。

代码

java 复制代码
class Solution {
    public List<Integer> pathInZigZagTree(int label) {
        int level = 1;
        int start = 1, end = 1;
        while (end < label) {
            level++;
            start *= 2;
            end = end * 2 + 1;
        }
        int num = level % 2 == 1 ? label : start + end - label;
        List<Integer> path = new ArrayList<Integer>();
        while (num > 0) {
            int curr = level % 2 == 1 ? num : start + end - num;
            path.add(curr);
            num /= 2;
            level--;
            start /= 2;
            end /= 2;
        }
        Collections.reverse(path);
        return path;
    }
}

复杂度分析

  • 时间复杂度: O ( log ⁡ label ) O(\log \textit{label}) O(loglabel)。定位到标号为 label \textit{label} label 的结点所在的层需要 O ( log ⁡ label ) O(\log \textit{label}) O(loglabel) 的时间,得到从根结点到标号为 label \textit{label} label 的结点的路径也需要 O ( log ⁡ label ) O(\log \textit{label}) O(loglabel) 的时间。

  • 空间复杂度: O ( 1 ) O(1) O(1)。除了返回值以外,使用的空间是常数。

相关推荐
KaiPeng-Nie7 天前
代码随想录day21 | leetcode 669.修剪二叉搜索树 108.将有序数组转换为二叉搜索树 538.把二叉搜索树转换为累加树 二叉树总结篇
java·数据结构·算法·leetcode·二叉树
『往事』&白驹过隙;10 天前
数据结构与算法汇总整理篇——链表与二叉树(常用特性的概念及细节处理)
数据结构·c++·学习·leetcode·链表·面试·二叉树
2401_8582861111 天前
111.【C语言】数据结构之二叉树的销毁函数
c语言·开发语言·数据结构·二叉树
小殷要努力刷题!13 天前
每日一刷——12.10——学习二叉树解题模式(1)
java·学习·算法·leetcode·二叉树·二叉树的建立
2401_8582861118 天前
L15.【LeetCode笔记】相同的树
c语言·开发语言·数据结构·笔记·算法·leetcode·二叉树
不修×蝙蝠20 天前
数据结构--二叉树的创建和遍历
java·数据结构·二叉树·深度遍历·广度遍历·迭代法·递归法
不修×蝙蝠22 天前
数据结构--二叉树删除树节点
数据结构·二叉树··删除·删除节点
瞌睡不来22 天前
(C++ STL) set、multiset、map、multimap 类的简单模拟实现与源码展示
数据结构·c++·学习·二叉树·set·map·c++ stl
2401_8582861123 天前
108.【C语言】数据结构之二叉树查找值为x的节点
c语言·开发语言·数据结构·笔记·二叉树
Bucai_不才1 个月前
【数据结构】树——链式存储二叉树的基础
数据结构·二叉树