数组表示的二叉树

面试某厂的时候面试官问了二叉树最长路径的算法题,给定一个数组找出最长路径的值,第一反应就是动态规划,结果手写代码的时候懵逼想不起怎么通过子节点推算父节点的下标,特此记录警世自己。

 

fun main(args: Array<String>) {
    val t = Tree()
    t.printParentNode(1)
    t.printParentNode(2)
    t.printParentNode(3)
    t.printParentNode(4)
    t.printParentNode(5)
    t.printParentNode(6)
    t.printParentNode(7)
    t.printParentNode(8)
    t.printParentNode(9)
}

class Tree {

    private val data : IntArray = intArrayOf(9,6,4,8,3,7,2,10,25,7)

    /**                                         下标                第n个节点
     *                              9            0                      1
     *                           /    \
     *                          6      4        1 2        1层         2 3
     *                         / \     /\
     *                        8   3   7  2     3 4 5 6     2层        4 5 6 7
     *                       / \  /
     *                      10 25 7            7 8 9       3层        8 9 10
     *
     *                     某个数组中某个index i,对应的父节点下标是:(i+1)/2 - 1
     *                     如(3+1)/2-1 = 1   (4+1)/2-1 = 1
     *                     (8+1)/2-1 = 3    (9+1)/2-1 = 4
     *
     */



    fun printParentNode(i : Int): Unit {
        println("index $i 值是${data[i]} 对应的父节点是 ${data[(i+1)/2-1]}")
    }

}

输出:

index 1 值是6 对应的父节点是 9
index 2 值是4 对应的父节点是 9
index 3 值是8 对应的父节点是 6
index 4 值是3 对应的父节点是 6
index 5 值是7 对应的父节点是 4
index 6 值是2 对应的父节点是 4
index 7 值是10 对应的父节点是 8
index 8 值是25 对应的父节点是 8
index 9 值是7 对应的父节点是 3

 

 

面试题的代码解法如:

fun maxLen(): Int {
        val tmp = intArrayOf(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1)
        data.forEachIndexed {
            index, i ->
            tmp[index] = if (index == 0) 0 else {
                val parentIndex = (index+1)/2-1
                if (tmp[parentIndex] + i > tmp[index-1]) tmp[parentIndex] + i else tmp[index-1]
            }
        }
        println("最长路径:")
        tmp.forEach {
            i: Int -> print("$i,")
        }
        return tmp[tmp.lastIndex]
    }

输出:

最长路径:
0,6,6,14,14,14,14,24,39,39,

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值