669. 修剪二叉搜索树
这题可以写一个删除节点的函数,然后遍历所有节点,如果不在范围内就删掉,试一下
dubug两次后过了
class Solution:
def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
if not root: return root
root.left = self.trimBST(root.left,low,high)
root.right = self.trimBST(root.right,low,high)
if root.val < low or root.val > high:
return self.deleteNode(root,root.val)
return root
def deleteNode(self,root,val):
if not root: return root
if root.val == val:
if not root.left and not root.right:
return None
elif not root.left:
return root.right
elif not root.right:
return root.left
else:
cur = root.right
while cur.left is not None:
cur = cur.left
cur.left = root.left
return root.right
if root.val > val:
root.left = self.deleteNode(root.left,val)
if root.val < val:
root.right = self.deleteNode(root.right,val)
return root
这个逻辑有点奇怪的地方在于必须在主函数里使用后序遍历,最后处理中间节点是否需要删掉,因为若根节点被删掉就直接返回了
看一下解答的思路
class Solution:
def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
if not root: return root
if root.val < low: return self.trimBST(root.right,low,high)
if root.val > high: return self.trimBST(root.left,low,high)
root.left = self.trimBST(root.left,low,high)
root.right = self.trimBST(root.right,low,high)
return root
简洁多了,而且意识到自己写的那个思路不需要后序遍历,只要处理根节点值的时候递归调用本函数即可
class Solution:
def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
if not root: return root
if root.val < low or root.val > high:
return self.trimBST(self.deleteNode(root,root.val),low,high)
root.left = self.trimBST(root.left,low,high)
root.right = self.trimBST(root.right,low,high)
return root
108 将有序数组转换为二叉搜索树
单纯构建二叉搜索树不难,但要求是高度平衡的,也即两边子树高度差不超过1,这意味着最好是左边加一个,右边加一个。。也就是从数组中间开始取值,左边取一个放左边,右边取一个放右边?
思路有误,这样只能保证根节点左右平衡并不能保证每个节点平衡,需要递归对每个节点这样操作,ok通过
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
if len(nums) == 0: return None
if len(nums) == 1: return TreeNode(nums[0])
mid = int(len(nums)/2)
root = TreeNode(nums[mid])
left = nums[:mid]
right = nums[mid+1:]
root.left = self.sortedArrayToBST(left)
root.right = self.sortedArrayToBST(right)
return root
好像比解答还要简洁一点,善用递归赋值
538 把二叉搜索树转换为累加树
累加树,需要找每个节点右子树上所有节点数字之和加上它本身的值,可以用回溯的思想,后序遍历?不对,累加顺序实际上是右根左
或者可以找右子树上最左边的叶子值,然后加本身,这样就不用重新生成二叉树了
想到了可以用右中左遍历顺序,但是没写出来
class Solution:
def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
self.pre = 0
self.accumulate(root)
return root
def accumulate(self,root):
if not root: return
self.accumulate(root.right)
root.val += self.pre
self.pre = root.val
self.accumulate(root.left)
解答的思路很简洁,也理清了我自己的想法,只在根节点处理self.sum
class Solution:
def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
self.sum = 0
self.accumulate(root)
return root
def accumulate(self,root):
if not root: return 0
self.accumulate(root.right)
self.sum += root.val
root.val = self.sum
self.accumulate(root.left)
左右子树只遍历
二叉树总结
四种遍历方式一定要会,需要重点掌握递归前中后序,统一风格的前中后迭代法,层序遍历