每日算法题—二叉树寻路

题目描述

在一棵无限的二叉树上,每个节点都有两个子节点,节点按照下图顺序排列,给定一个节点,求该节点到根节点的路径。



如:输入节点14,返回[1,3,4,14]

思路

这道题我认为是到数学题,本质上是要找到知道子节点退出父节点的公式和该节点位于第几层,然后不断的往上求父节点的值就可以了。
试想如果节点排序是一个方向,而不是交错的排列,如下图:


那么4=22,5=22+1,6=32,7=32+1
即:节点x,其左孩子=2x,右孩子=2x+1
上面是节点的顺序是一个方向的情况,如果按照题目的顺序又是怎么样呢?
举个例子:1 2 3 4 5 6 7 8
现在变成了8 7 6 5 4 3 2 1 ,相当于位置发生了镜像交换,
1—>8 2—>7 3—>6 4—>5
他们加起来的总数是不变得,所以知道1 可以 通过(1+8)-1计算出8
假设这一排个数为T个,那么第x个数镜像交换后的值为
(第1个数+第T个数)-第x个数

回到题目中,5 的左孩子本来是10 ,但是现在被镜像交换了,所以可以求得5现在的左孩子是:(8+15)-10 = 13
同理:7现在的左孩子是:(8+15)-14 = 9
由于这棵树每个节点都有左右孩子,第L层的第一个值是:2^L, 最后一个值是:2^(L+1) - 1
假设节点N,位于第L层,那么其左节点=2^L + 2^(L+1)-1 - 2N
那么知道一个节点反推其父节点,比如知道左节点的值left,求父节点的值:
父节点=(2^L + 2^(L+1) -1-left)/2
比如:5 = (2^3 + 2^4 -1-13)/2 = (8+15-13)/2 = 5
刚才那是左节点的情况,其实右节点推父节点也是一样的:
比如:5 = (2^3 + 2^4-1-12)/2 = (8+15-12)/2 = 11/2 = 5
因为int 除以 int 最后小数被忽略了,所以结果还是5
所以我们得到了知道子节点求父节点的公式:(2^L + 2^L +1-1-left)/2
现在唯一不知道的就是怎么求出L,即子节点是在那一层,假设节点值为N,求L:
不慌,虽然数学老师教我们的知识都差不多忘了,但是我们是程序员,有本办法,从前面知道每一层的数都在 2^L 至 2^(L+1) -1 之间,所以大不了写个循环判断嘛,很简单,另一个办法就是想起被数学支配的恐惧:直接求对数,L=logN/log2+1 别问,问就是不知道

所以到此我们总结下,已知节点N,求其父节点步骤:

  1. 求出N所在层,即:L = logN/log2+1
  2. 再求父节点:(2^L + 2^(L+1) -1-N)/2

有了两个公式代码就好写了

实现

  fun pathInZigZagTree(label: Int): List<Int> {
        var level = (Math.log(label.toDouble()) / Math.log(2.0)).toInt() + 1//求出节点所在的层
        println(level)
        val list = arrayListOf<Int>()
        list.add(label)
        var result: Int = label
        while (level > 1) {//有多少层,就有多少个父节点
            result = p(result, level--)
            list.add(0, result)
        }
        return list
    }

    fun p(label: Int, level: Int): Int {
        println("" + label + " " + level)
        var l = level - 1//
        val total: Int = (Math.pow(2.0, l.toDouble()) + Math.pow(2.0, (l + 1).toDouble()) - 1).toInt() //求出这一层首个节点值+最后个节点值总和
        return (total - label) / 2//求出父节点值
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 二叉树 1 二叉树简介 二叉树是树的特殊一种,具有如下特点: 1、每个结点最多有两颗子树,结点的度最大为2。2、左...
    孔雨露阅读 4,455评论 0 2
  • 介绍 二叉树的结构 二叉树常考的原因有如下几点1、它可以结合链表、栈、队列和字符串等数据结构出题2、需要熟练掌握图...
    雨住多一横阅读 3,233评论 0 1
  • 树形结构 在前面章节中介绍到的数据结构,都为线性结构,比如链表,数组,队列等,都属于线性结构,类似于通过一根线串在...
    ducktobey阅读 5,098评论 0 0
  • 树的基本概念 节点,根节点,父节点,子节点,兄弟节点都是属于树的范涛; 一棵树可以没有任何节点,称为空树; 一棵树...
    coder_feng阅读 4,855评论 0 0
  • 生活中 谁都会被工作缠身 情感交织或友情或恋情 此情此景 有人处理的好 有人却乱糟糟 众所周知 杨雄是一个大忙人 ...
    旖旎i阅读 1,137评论 2 11