版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dpengwang/article/details/88327308
对二叉排序树进行剪枝,保证其每个节点的值都在某个范围之类
方法1 递归法
递归的形式很好写,对每个节点进行递归,如果当前节点在取值范围之类,递归处理其左右子树,如果不满足,返回递归处理后的左子树或右子树。
注意这里的递归处理子树和返回递归处理后的子树的区别。
递归处理子树说明没有发生剪枝
返回递归递归处理的子树说明发生了剪枝
class Solution(object):
def trimBST(self, root, L, R):
"""
:type root: TreeNode
:type L: int
:type R: int
:rtype: TreeNode
"""
if root==None :return None
# 返回递归处理后的子树
if root.val > R:return self.trimBST(root.left,L,R)
if root.val <L:return self.trimBST(root.right,L,R)
# 递归处理子树
root.left =self.trimBST(root.left,L,R)
root.right=self.trimBST(root.right,L,R)
return root
方法2 非递归法
递归法比较难写,目前只弄明白一种,后续有的话再补充。
流程:
- 首先我们找到最终结果的根节点,即满足node.val in [L,R],注意这里是闭区间。
- 然后分别对root的左右子树进行处理,剪去左子树中小于L的子树,剪去右子树中大于R的子树,分左右子树分别处理的好处是,拿左子树为例,如果当前节点满足大于L,我们就不用处理其右子树了,直接处理左子树即可。
- 由于对树中的节点有删除操作,所以我们需要保存当前节点的父节点。
大神们的思路就是牛啊
class Solution2(object):
def trimBST(self, root, L, R):
"""
:type root: TreeNode
:type L: int
:type R: int
:rtype: TreeNode
"""
# 找到满足条件的根节点这样后面只要分别对其左右子树进行处理即可
if root == None:
return None
while(root and (root.val < L or root.val > R)):
if root.val < L:
root = root.right
elif root.val > R:
root = root.left
#对左子树进行剪枝,保证左子树的值都大于等于L,对于每个节点,如果其满足条件,那么其右子树肯定也是满足的
#我们再对其左子树进行剪枝就行了
l , parent = root, root
while(l):
# 该条件第一次循环的时候肯定是满足的
# parent 为满足条件的点
if l.val > L:
parent = l
l = l.left
elif l.val == L:
l.left = None
break
else:
parent.left = l.right
l = l.right
#对右子树进行剪枝,保证其右子树的值都小于等于R, 对于每个节点,如果其满足条件,那么其左子树肯定也是满足的
#我们再对其右子树进行剪枝就行了
r, parent = root, root
while(r):
if r.val < R:
parent = r
r = r.right
elif r.val == R:
r.right = None
break
else:
#就算是r的左子树,其值也是比其父节点值大,所以归入其右孩子
parent.right = r.left
r = r.left
return root