LeetCode-Python- 366. 寻找完全二叉树的叶子节点

642 篇文章 23 订阅

给你一棵完全二叉树,请按以下要求的顺序收集它的全部节点:

依次从左到右,每次收集并删除所有的叶子节点
重复如上过程直到整棵树为空
示例:

输入: [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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值