LeetCode-Python-1325. 删除给定值的叶子节点(DFS + 拓扑排序)

给你一棵以 root 为根的二叉树和一个整数 target ,请你删除所有值为 target 的 叶子节点 。

注意,一旦删除值为 target 的叶子节点,它的父节点就可能变成叶子节点;如果新叶子节点的值恰好也是 target ,那么这个节点也应该被删除。

也就是说,你需要重复此过程直到不能继续删除。

示例 1:

输入:root = [1,2,3,2,null,2,4], target = 2
输出:[1,null,3,null,4]
解释:
上面左边的图中,绿色节点为叶子节点,且它们的值与 target 相同(同为 2 ),它们会被删除,得到中间的图。
有一个新的节点变成了叶子节点且它的值与 target 相同,所以将再次进行删除,从而得到最右边的图。
示例 2:

输入:root = [1,3,3,3,2], target = 3
输出:[1,3,null,null,2]
示例 3:

输入:root = [1,2,null,2,null,2], target = 2
输出:[1]
解释:每一步都删除一个绿色的叶子节点(值为 2)。
示例 4:

输入:root = [1,1,1], target = 1
输出:[]
示例 5:

输入:root = [1,2,3], target = 1
输出:[1,2,3]
 

提示:

1 <= target <= 1000
每一棵树最多有 3000 个节点。
每一个节点值的范围是 [1, 1000] 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/delete-leaves-with-a-given-value
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

第一种思路:

树的问题首先考虑是否可以DFS递归解,

对于一棵树,如果左子树已经处理好了,右子树也处理好了,

那么剩下的根节点要解决的就很简单了:

如果左右孩子都为空,而且根节点的值也为target,返回None,

否则返回根节点。

时间复杂度:O(N)

空间复杂度:O(N)

class Solution(object):
    def removeLeafNodes(self, root, target):
        """
        :type root: TreeNode
        :type target: int
        :rtype: TreeNode
        """
        if not root:
            return root
        root.left = self.removeLeafNodes(root.left, target)
        root.right = self.removeLeafNodes(root.right, target)
        if not root.left and not root.right and root.val == target:
            return None
        return root  

第二种思路:

类似LeetCode-Python- 366. 寻找完全二叉树的叶子节点,只是额外多加了一个target的条件,

所以也可以利用拓扑排序进行解题。

时间复杂度:O(N)

空间复杂度:O(N)

class Solution(object):
    def removeLeafNodes(self, root, target):
        """
        :type root: TreeNode
        :type target: int
        :rtype: TreeNode
        """
        from collections import defaultdict, deque
        if not root:
            return root
        outdegree = dict()
        parent = dict()
        
        # 层序遍历预处理
        queue = deque([root])
        while queue:
            for _ in range(len(queue)):
                cur = queue.popleft()
                outdegree[cur] = 0
                if cur.left:
                    outdegree[cur] += 1
                    parent[cur.left] = cur
                    queue.append(cur.left)
                if cur.right:
                    outdegree[cur] += 1
                    parent[cur.right] = cur
                    queue.append(cur.right)
                    
        queue = deque([])
        for key, val in outdegree.items():
            if not val and key.val == target:
                queue.append(key)
        
        while queue:
            cur = queue.popleft()
            if cur not in parent:
                return None
            par = parent[cur]
            if par.left and par.left == cur:
                par.left = None
                outdegree[par] -= 1
            if par.right and par.right == cur:
                par.right = None
                outdegree[par] -= 1
            
            if outdegree[par] == 0 and par.val == target:
                queue.append(par)
                
        return root
发布了687 篇原创文章 · 获赞 88 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/qq_32424059/article/details/104073957