题目:
给定二叉树根结点 root
,此外树的每个结点的值要么是 0,要么是 1。
返回移除了所有不包含 1 的子树的原二叉树。
( 节点 X 的子树为 X 本身,以及所有 X 的后代。)
示例1:
输入: [1,null,0,0,1]
输出: [1,null,0,null,1]
解释:
只有红色节点满足条件“所有不包含 1 的子树”。
右图为返回的答案。
示例2:
输入: [1,0,1,0,0,0,1]
输出: [1,null,1,null,1]
示例3:
输入: [1,1,0,1,1,0,1,0]
输出: [1,1,0,1,1,null,1]
本题依然是一个 递归函数+辅助函数 只不过辅助函数也是一个递归
思路:
观察发现 一个节点的val是0 而子树的节点中存在1,我们可就无法删除该节点的子树
所以我做了一个比喻 "挖金矿"
把1当做金子 当开始挖掘(遍历)某一个节点的子树时,一旦发现该节点的子树存在金子(1)时,就不向下挖掘(遍历),开始返回挖掘点,告诉挖掘点 下面有金子(即: 存在1,不能删除该(左/右)子树)
当挖掘到底(遍历到叶子结点)时,仍未挖掘到金子(没有1),则返回挖掘层,没有金子(即: 不存在1,要删除该(左/右)子树)
以下是核心代码:
//Definition for a binary tree node.
type TreeNode1 struct {
Val int
Left *TreeNode1
Right *TreeNode1
}
func printTree(node *TreeNode1){
if node ==nil{
return
}
printTree(node.Left)
if has_zero(node.Left,true)==true{ //挖掘层 探测该node的左子树是否存在1 当存在1时,不能删除整个左子树
node.Left = nil
}
printTree(node.Right)
if has_zero(node.Right,true)==true{ //挖掘层 探测该node的右子树是否存在1 当存在1时,不能删除整个右子树
node.Right = nil
}
}
func has_zero(node *TreeNode1,boolean bool)(bool){ //挖掘函数
if boolean == false{
return boolean
}
if node==nil{
return boolean
}else{
if node.Val == 1 { //发现层 当发现该树存在1的节点 则可以一直向上传递(传递层) 即: "跳出"has_zero递归
boolean=false
return boolean
}
}
if node.Left!=nil {
if has_zero(node.Left,boolean)==false{ //挖掘层
boolean=false
return boolean //传递层 当得知boolean=false时(存在1节点) 就进行向上传递
}
}
if node.Right!=nil{
if has_zero(node.Right,boolean)==false{ //挖掘层
boolean=false
return boolean //同上
}
}
return boolean
}
func pruneTree(root *TreeNode1) *TreeNode1 {
printTree(root)
return root
}