本文为Python算法题集之一的代码示例
给你二叉树的根结点 root
,请你将它展开为一个单链表:
TreeNode
,其中 right
子指针指向链表中下一个结点,而左子指针始终为 null
。示例 1:
输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [0]
输出:[0]
提示:
[0, 2000]
内-100 <= Node.val <= 100
**进阶:**你可以使用原地算法(O(1)
额外空间)展开这棵树吗?
通常优化:减少循环层次
通常优化:增加分支,减少计算集
通常优化:采用内置算法来提升计算速度
分析题目特点,分析最优解
可以考虑使用DFS、BFS进行先序遍历,生成遍历结果,然后再生成链表,这样会得到链表和与其同步的列表数据【检索方便】
可以不生成遍历结果,直接将二叉树变形为链表,这样就必须将根节点的左子树最右节点的右指针指向根节点的右子树,此方法空间复杂度为0(1)
CheckFuncPerf
(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块使用深度优先算法执行先序遍历,然后生成链表
import CheckFuncPerf as cfp
class Solution:
def flatten_base(self, root):
def dfspreorder(root, listnode):
if root is None:
return []
listnode.append(root)
dfspreorder(root.left, listnode)
dfspreorder(root.right, listnode)
list_node = []
dfspreorder(root, list_node)
for iIdx in range(len(list_node)-1):
list_node[iIdx].left = None
list_node[iIdx].right = list_node[iIdx+1]
aSolution = Solution()
aroot = generate_binary_tree(ilen, imode)
result = cfp.getTimeMemoryStr(Solution.flatten_base, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result']))
# 运行结果
函数 flatten_base 的运行时间为 271.27 ms;内存使用量为 40.00 KB 执行结果 = None
使用广度优先算法执行先序遍历,然后生成链表
import CheckFuncPerf as cfp
class Solution:
def flatten_ext1(self, root):
if root is None:
return []
list_node = []
stack = [root]
while stack:
node = stack.pop()
list_node.append(node)
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
for iIdx in range(len(list_node)-1):
list_node[iIdx].left = None
list_node[iIdx].right = list_node[iIdx+1]
aSolution = Solution()
aroot = generate_binary_tree(ilen, imode)
result = cfp.getTimeMemoryStr(Solution.flatten_ext1, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result']))
# 运行结果
函数 flatten_ext1 的运行时间为 252.33 ms;内存使用量为 756.00 KB 执行结果 = None
使用深度优先算法执行遍历,过程中直接将二叉树改为链表
import CheckFuncPerf as cfp
class Solution:
def flatten_ext2(self, root):
def dtspreorder(root):
if root == None:
return
dtspreorder(root.left)
dtspreorder(root.right)
if root.left != None:
nextnode = root.left
while nextnode.right:
nextnode = nextnode.right
nextnode.right = root.right
root.right = root.left
root.left = None
dtspreorder(root)
aSolution = Solution()
aroot = generate_binary_tree(ilen, imode)
result = cfp.getTimeMemoryStr(Solution.flatten_ext2, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result']))
# 运行结果
函数 flatten_ext2 的运行时间为 653.25 ms;内存使用量为 0.00 KB 执行结果 = None
使用广度优先算法执行遍历,过程中直接将二叉树改为链表
import CheckFuncPerf as cfp
class Solution:
def flatten_ext3(self, root):
while (root != None):
if root.left != None:
nextnode = root.left
while nextnode.right != None:
nextnode = nextnode.right
nextnode.right = root.right
root.right = root.left
root.left = None
root = root.right
aSolution = Solution()
aroot = generate_binary_tree(ilen, imode)
result = cfp.getTimeMemoryStr(Solution.flatten_ext3, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result']))
# 运行结果
函数 flatten_ext3 的运行时间为 162.54 ms;内存使用量为 0.00 KB 执行结果 = None
根据本地日志分析,最优算法为第4种方式【BFS迭代+直接转换】flatten_ext3
import random
ilen, imode = 1000000, 1
def generate_binary_tree(node_count, imode):
if node_count <= 0:
return None
root = TreeNode(random.randint(1, 100))
node_count -= 1
if imode > 3:
imode = 1
if imode == 1:
left = generate_binary_tree(node_count // 2, imode+1)
right = generate_binary_tree(node_count // 2, imode+1)
root.left = left
root.right = right
elif imode==2:
left = generate_binary_tree(node_count, imode+1)
root.left = left
else:
right = generate_binary_tree(node_count, imode+1)
root.right = right
return root
aSolution = Solution()
aroot = generate_binary_tree(ilen, imode)
result = cfp.getTimeMemoryStr(Solution.flatten_base, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result']))
aroot = generate_binary_tree(ilen, imode)
result = cfp.getTimeMemoryStr(Solution.flatten_ext1, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result']))
aroot = generate_binary_tree(ilen, imode)
result = cfp.getTimeMemoryStr(Solution.flatten_ext2, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result']))
aroot = generate_binary_tree(ilen, imode)
result = cfp.getTimeMemoryStr(Solution.flatten_ext3, aSolution, aroot)
print(result['msg'], '执行结果 = {}'.format(result['result']))
# 算法本地速度实测比较
函数 flatten_base 的运行时间为 271.27 ms;内存使用量为 40.00 KB 执行结果 = None
函数 flatten_ext1 的运行时间为 252.33 ms;内存使用量为 756.00 KB 执行结果 = None
函数 flatten_ext2 的运行时间为 653.25 ms;内存使用量为 0.00 KB 执行结果 = None
函数 flatten_ext3 的运行时间为 162.54 ms;内存使用量为 0.00 KB 执行结果 = None
一日练,一日功,一日不练十日空
may the odds be ever in your favor ~