给你一棵完全二叉树,请按以下要求的顺序收集它的全部节点:
依次从左到右,每次收集并删除所有的叶子节点
重复如上过程直到整棵树为空
示例:
输入: [1,2,3,4,5]
1
/ \
2 3
/ \
4 5
输出: [[4,5,3],[2],[1]]
解释:
1. 删除叶子节点 [4,5,3] ,得到如下树结构:
1
/
2
2. 现在删去叶子节点 [2] ,得到如下树结构:
1
3. 现在删去叶子节点 [1] ,得到空树:
[]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-leaves-of-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
第一种解法:
暴力解,不断地遍历整棵树,每次取出当前所有的叶子节点。
class Solution(object):
def findLeaves(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if not root:
return []
res = []
s = set()
def helper(pre, node, tmp):
if not node or node in s:
return
if not node.left and not node.right and node != root:
if pre.left == node:
pre.left = None
elif pre.right == node:
pre.right = None
tmp.append(node.val)
s.add(node)
return
helper(node, node.left, tmp)
helper(node, node.right, tmp)
while root.left or root.right:
tmp = []
helper(None, root, tmp)
res.append(tmp)
# print res
res.append([root.val])
return res
第二种解法:
类似207 和 210 用拓扑排序解题,
区别在于207和210是用入度,本题用出度。
class Solution(object):
def findLeaves(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if not root:
return []
from collections import defaultdict
outdegree = defaultdict(int)
adjancency = defaultdict(set)
queue = [root]
while queue:
# print queue
next_queue = []
for i in range(len(queue)):
node = queue[i]
outdegree[node] = 0
if node.left:
outdegree[node] += 1
adjancency[node.left].add(node)
next_queue.append(node.left)
if node.right:
outdegree[node] += 1
adjancency[node.right].add(node)
next_queue.append(node.right)
queue = next_queue[:]
# print outdegree
# print adjancency
queue = []
for node, odegree in outdegree.items():
if odegree == 0: #it's a leaf node
queue.append(node)
res = []
while queue:
tmp = []
for node in queue:
tmp.append(node.val)
res.append(tmp[:])
next_queue = []
for node in queue:
for neibor in adjancency[node]:
outdegree[neibor] -= 1
if outdegree[neibor] == 0:
next_queue.append(neibor)
queue = next_queue[:]
return res
第三种思路:
观察题意可知,最后输出的结果实际上就是按高度升序排列的节点,
比如
输入: [1,2,3,4,5]
1
/ \
2 3
/ \
4 5
输出: [[4,5,3],[2],[1]]
其中4, 5, 3就是高度为1的节点,2 就是高度为2的节点,1就是高度为3的节点,
所以只要找到所有节点的高度,即可生成这样的结果数组。
class Solution(object):
def findLeaves(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if not root:
return []
h_dict = collections.defaultdict(int) #
record = collections.defaultdict(set) # key is the height, val is the node
def findHeight(node):
if not node:
return
# print node.val
if not node.left and not node.right:
h_dict[node] = 1
record[1].add(node)
return
if node.left not in h_dict:
findHeight(node.left)
if node.right not in h_dict:
findHeight(node.right)
h_dict[node] = 1 + max(h_dict[node.left], h_dict[node.right])
record[h_dict[node]].add(node)
findHeight(root)
res = []
for i in range(1, max(record.keys()) + 1):
tmp = []
for node in record[i]:
tmp.append(node.val)
res.append(tmp[:])
return res
第四种思路:
类似思路三,但是实现更加简洁。
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def findLeaves(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if not root:
return None
res = []
def dfs(node):
if not node:
return 0
depth = max(dfs(node.left), dfs(node.right))
if len(res) < depth + 1:
res.append([])
res[depth].append(node.val)
return depth + 1
dfs(root)
return res