xmldocument如何创建一个不带结尾的节点_LeetCode基础算法题第129篇:列出二叉树根到叶子节点的所有路径...

a8da9a6a73ff315da016786ba9a75be4.png

技术提高是一个循序渐进的过程,所以我讲的leetcode算法题从最简单的level开始写的,然后> 到中级难度,最后到hard难度全部完。目前我选择C语言,Python和Java作为实现语言,因为这三种语言还是比较典型的。由于篇幅和> 精力有限,其他语言的实现有兴趣的朋友请自己尝试。初级难度说的差不多的时候,我打算再加点其他内容,我可能会从操作系统到协议栈,从分布式> 聊到大数据框架,从大数据聊到人工智能,... ...。

如果有任何问题可以在文章后评论或者私信给我。

我会持续分享下去,敬请您的关注。

LeetCode 257. 二叉树的所有路径(Binary Tree Paths)

问题描述:

给定一个二叉树,返回所有从根节点到叶子节点的路径。

注: 叶子节点是指没有子节点的节点。

示例:

cdc6e227332e613c8ac952807fb2adf2.png

C语言实现:

很明显我们通过前序遍历就可以求出。

当我们遍历到叶子节点的时候,我们需要知道从根到该节点的路径,所以我们要在遍历的过程中保存经过的节点路径,我们可以通过一个字符指针来保存,我们定义它为tmp。

过程很简单,但是有两个棘手的问题:

  1. 我们无法知道有多少个路径字符串;
  2. 我们无法知道每个路径字符串的确切长度;

当然第一个问题等价于有多少个叶子节点。

我们可以通过对树root遍历一次求出叶子节点树来获得,但是我们完全不必这么做。

我更倾向于通过realloc动态调节,而不是通过额外的遍历来先获得叶子节点数。

第二个问题可能才是比较困难的。如果静态给定一个长度,很可能是不够的,因为题目没有限定root的规模以及节点的val的取值。解决方法有两个:

  1. 先给定一个长度,然后每次判断一下,如果不够再realloc扩展,这种方法显然不太好。
  2. 比较好的办法是用asprintf函数来代替sprintf函数来填充tmp。

估计知道asprintf函数的朋友不太多,这是一个从BSD中移植到Linux中的函数,它和sprintf功能基本一致,区别是对于第一个参数,asprintf会动态的为其分配空间,以使其足够容纳内容,这意味着第一个参数可以为NULL,也不会存现字符串溢出的问题,更安全。

详细代码如下:

e8545e7cfd71825fee3537202a5e7a78.png

我们定义一个traverse函数来实现遍历,并填充res。

如果是当前节点是叶子节点:则创建路径字符串,并动态扩展res的长度,将新的路径字符串添加到res的结尾。

如果当前节点不是叶子节点:创建临时字符串给tmp。如果存在左右子节点,则将tmp传递过去,继续向下递归,直到碰到叶子节点。

注意第30行,tmp如果仅仅是产生的临时的中间字符串,而不是作为最终要添加到res中的字符串,那么递归回溯的过程一定要释放掉,否则会出现内存泄漏的问题,因为asprintf每次都会动态的为tmp分配内存空间。所以不要认为tmp总是不变的保存在res中的那个。

c20ff1724d2d754e9081793218cb9d82.png

注意 *returnSize 的初始化一定要在判断root是否为空的前面。我之前就没有注意这个顺序,总是提交不了,当root为空时报运行时错误,就是因为这个问题。

root为空直接返回了,如果 *returnSize 未初始化初始化当然会出错。

d8289bf300ccf8caae064a3d929a17e7.png

Java语言实现:

Java 的实现和C语言的实现类似,只是要简单的多,不用考虑列表和字符串长度的问题。

代码如下:

5c561995d7d12aeeea362aca232bee36.png
d73e833bf4bfe979609c8128891b0a02.png

Python语言实现:

Python 的实现和Java语言的实现类似,但要更简单。

路径我们可以通过列表生成器+递归方式获得。

这里注意函数声明中已经说明,返回的列表中的元素必须是字符串,所以注意第14行,root.val要强制转换成str。否则对于某些case会过不了。

代码如下:

26adc89902d156941601759e8640167d.png
a1c8b1d8c08179ceb363c83f0d60e32d.png

谢谢大家一直以来的关注和支持!

我一直在努力的写好每一篇文章,画好每一份插图。但是作为一个996从业人员,时间精力十分有限。所以针对评论部分,以后只回答粉丝的问题和私信。希望仅仅是路过的朋友能够体谅,希望更多人关注《吾是我师》,谢谢!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值