前言:
“根据二叉树创建字符串”的题目是力扣题库上的第606题。我是使用Python3编写的解法,性能算不上好,在此仅仅只是阐述一下解法编程思想。仅供参考~
解法上可能会跟别人相同,所以要是看不懂下面的阐述的话可以去力扣对应的题目上查看其他人的解题思路~
问题描述:
题目的要求是:你需要采用前序遍历的方式,将一个二叉树转换成一个由括号和整数组成的字符串。
空节点则用一对空括号 "()" 表示。而且你需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。
LeetCode官方给的示例如下:
示例1:
输入: 二叉树: [1,2,3,4]
1
/ \
2 3
/
4
输出: "1(2(4))(3)"
解释: 原本将是“1(2(4)())(3())”,
在你省略所有不必要的空括号对之后,
它将是“1(2(4))(3)”。
示例2:
输入: 二叉树: [1,2,3,null,4]
1
/ \
2 3
\
4
输出: "1(2()(4))(3)"
解释: 和第一个示例相似,
除了我们不能省略第一个对括号来中断输入和输出之间的一对一映射关系。
解题思路:
像LeetCode给出的题目要求一样,采用前序遍历(根左右)的方式遍历树。 空节点则用一对空括号 "()" 表示。同时,题目也要求省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。也就是说,并不是所有的空节点都要用空括号表示,而是一些有必要的才需要用空括号表示。那么哪些空节点需要空括号表示,而哪些空节点不需要空括号表示呢?
对于需要用空括号表示的空节点,其实就是说某个节点的左孩子为空,但是右孩子不为空时,该节点的左孩子就需要用空括号表示。否则的话,输出字符串里面就不是一对一的映射关系了。
树:
1
/ \
2 3
\
4
如果节点2的左孩子不用()表示,则结果会为: 1(2(4))(3)
此时结果中的4是2的左孩子了。
对于不需要用空括号表示的空节点,则是说某个节点的右孩子为空,但是左孩子不为空时,该节点的右孩子就不需要用空括号表示。如示例1。
简而言之,解题的思路就是:使用前序遍历的方式遍历树,在某个节点遍历左孩子或右孩子前将“(”插入到字符串中,在遍历之后将“)”插入字符串。当某个节点的左孩子为空,当右孩子非空时,将“()”插入字符串中来代表该节点的左孩子;当某个节点的右孩子为空,则无需插入。
相关代码:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def tree2str(self, root: Optional[TreeNode]) -> str:
# 采用前序遍历的方式,将二叉树转换成字符串
def getFirst(root,ansList):
# 当前节点是否为空节点
if root is not None:
# 将当前节点的值插入字符串中
ansList[0]+=str(root.val)
# 当前节点是否有左孩子
if root.left is not None:
# 有左孩子,在遍历左孩子前插入“(”
ansList[0]+="("
# 遍历左孩子
getFirst(root.left,ansList)
# 将“)”插入字符串
ansList[0]+=")"
else:
# 当前节点无左孩子时,是否有右孩子
if root.right is not None:
# 当前节点无右孩子,插入“()”到字符串中,以表示其左孩子
ansList[0]+="()"
# 当前节点是否有右孩子
if root.right is not None:
# 有左孩子,在遍历右孩子前插入“(”
ansList[0]+="("
# 遍历右孩子
getFirst(root.right,ansList)
# 将“)”插入字符串
ansList[0]+=")"
# 定义列表,列表中的第一个元素为需要返回的字符串
ansList=[""]
# 调用函数getFirst
getFirst(root,ansList)
# 返回字符串
return ansList[0]
运行结果: