IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Leetcode 1104.二叉树寻路 -> 正文阅读

[数据结构与算法]Leetcode 1104.二叉树寻路

Leetcode 1104.二叉树寻路

题目链接: leetcode 1104.二叉树寻路

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

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

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

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

样例

示例1:
输入:label = 14
输出:[1,3,4,14]
    
示例2:
输入:label = 26
输出:[1,2,6,10,26]

提示:

  • 1 ≤ l a b e l ≤ 1 0 6 1 \le label \le 10^6 1label106?

算法1

思路分析

根据题意可以知道这是一棵完全二叉树, 如果其标记的顺序不是按照题目的之字形进行标记, 而是按照正常的从上到下,从左到右的顺序依次标记, 那么我们对于其标号x的关系有, 其左孩子为 2 * x, 其右孩子为 2 * x + 1; 其父节点为 x / 2 (x > 1); 此时对于根节点到label的路径为1–>…–> label / 4 --> label / 2 --> label。 那么按照题目的意思,此时偶数层的标号会被逆序, 奇数层保持不变。那么此时的label的情况就有两种.

(1) 此时label节点位于奇数层 (第 x 层, 根节点为第一层)

如果此时label位于奇数层, 那么此时其父节点即为偶数层, 其原本的父节点应该为 label / 2, 但由于偶数层相比于原本其顺序是相反的, 故此时的标号为 2 x ? 2 + 2 x ? 1 ? 1 ? l a b e l / 2 2^{x - 2} + 2^{x - 1} - 1 - label / 2 2x?2+2x?1?1?label/2, 这个式子是如何推到的呢? 首先对于label的上一层即第 x - 1层, 其原本的最左边的节点标记为 2 x ? 2 2^{x - 2} 2x?2 , 其最右边标记为 2 x ? 1 2^{x - 1} 2x?1 - 1, 而我们知道从左到右每个节点的标记都是递增1, 现在反转了标记顺序, 故可以得到原本的标记值 + 新的标记值 = 2 x ? 2 + 2 x ? 1 2^{x - 2} + 2^{x - 1} 2x?2+2x?1 - 1 所以知道原本的标记值应该为 label/2, 那么此时新的标记值为 2 x ? 2 + 2 x ? 1 ? 1 ? l a b e l / 2 2^{x - 2} + 2^{x - 1} - 1 - label / 2 2x?2+2x?1?1?label/2?.

(2) 此时label节点位于偶数层 (第 x 层)

同理如果此时的label位于偶数层, 那么此时的父节点即为奇数层, 即父节点的标记与原本完全二叉树的相同,而自身label是反转后的新值, 故我们要求出此时label的旧值, 然后用旧值 / 2 即得到父节点的标记值, 得到label旧值的方法同上, 此时旧标记值 + 新标记值(即label) = 2 x ? 1 + 2 x ? 1 2^{x - 1} + 2^x - 1 2x?1+2x?1, 故其原本的标记值为:

2 x ? 1 + 2 x ? 1 2^{x - 1} + 2^x - 1 2x?1+2x?1 - label , 故其父节点的值为 ( 2 x ? 1 + 2 x ? 1 2^{x - 1} + 2^x - 1 2x?1+2x?1? - label) / 2;

基于上面的分析, 那么我们最开始的时判断我们的label是偶数层还是奇数层, 首先这棵二叉树原本是属于完全二叉树, 故对于标记值为label, 且其位于的层数为x, 那么则存在 label < 2 x 2^x 2x?, 故这里我们可以用二分的方法快速求出label位于第几层。

C++ 代码

class Solution 
{
public:
    vector<int> pathInZigZagTree(int label) 
    {
        vector<int> res; 
        int l = 1, r = 20; 
        while(r > l)                     // 二分求出label位于第几层 
        { 
            int mid = l + r >> 1; 
            if(label <= pow(2, mid) - 1) r = mid; 
            else l = mid + 1; 
        }

        int n = l, num = label;        // n 表示当前层数, num 表示此时要加入的标记值 
        while(n != 1)
        {
            res.push_back(num); 
            if(n % 2) num = (pow(2, n - 2) + pow(2, n - 1) - 1  - num /  2); 
            else num = (pow(2, n - 1) + pow(2, n) - 1 - num) / 2; 
            --n;
        }

        res.push_back(1);                  // 最后加入根节点
        reverse(res.begin(), res.end());   // 由于从下往上遍历, 故最后要翻转
        return res; 
    }
};

时间复杂度 O ( l o g n ) O(logn) O(logn)


  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-31 16:53:22  更:2021-07-31 16:56:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 12:50:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码