114. 二叉树展开为链表
一开始写的:
#
# @lc app=leetcode.cn id=114 lang=python3
#
# [114] 二叉树展开为链表
#
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
def preorder(node):
if not node:
return
temp.append(node)
preorder(node.left)
preorder(node.right)
if not root:
return
temp=[]
preorder(root)
for i in range(len(temp)-1):
temp[i].left=None
temp[i].right=temp[i+1]
temp[len(temp)-1].left=None
temp[len(temp)-1].right=None
能通过,但看别人的题解发现题干写了“原地”,我这个申请了额外的数组保存前序遍历的节点显然不对了。然后看别人的后序做法又自己写。一个关键问题,为什么不能用中序或前序:因为题干最后要求的顺序是前序:即中,左,右, 在考察某特定节点时,将其左右子树全部处理完毕之前不能将该节点与其左右子树的连接改掉(想了半天),所以只有后序遍历的顺序是:左,右,中,在遍历到中节点的时候,左右子树已经处理好,此时可以改动中节点与左右子树的连接了。
下面是参考题解自己写的后序代码,思路就是先处理左右子树,然后处理根节点。根节点右指针连接左子树最右元素p(即前序前继),p右指针再连接根节点原右子树,这样就是中,左,右的前序顺序了。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
def func(node):
if not node:
return
func(node.left)
func(node.right)
p=node.left
while p and p.right:
p=p.right
if p:
node_right=node.right
node.right=node.left
node.left=None
p.right=node_right
func(root)
又写了个迭代的:先处理右子树成一条链表,再处理左子树成一条链表,然后和根节点连起来。。
class Solution:
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
if not root:
return
le,ri=None,None
if root.left:
le=root.left
if root.right:
ri=root.right
while ri and (ri.left or ri.right):
if not ri.left:
ri=ri.right
else:
p=ri.left
while p.right:
p=p.right
ri_right=ri.right
ri.right=ri.left
p.right=ri_right
ri.left=None
ri=ri.right
while le and (le.left or le.right):
if not le.left:
le=le.right
else:
p=le.left
while p.right:
p=p.right
le_right=le.right
le.right=le.left
p.right=le_right
le.left=None
le=le.right
if le:
le.right=root.right
root.right=root.left
root.left=None
然后我发现:我为啥要分左右子树再串起来??明明从根节点一个while循环就行了,脑子抽了!!
class Solution:
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
if not root:
return
x=root
while x and (x.left or x.right):
if not x.left:
x=x.right
else:
p=x.left
while p.right:
p=p.right
x_right=x.right
x.right=x.left
p.right=x_right
x.left=None
x=x.right
进击的小🐴农