二叉搜索树特性问题
LeetCode700题 二叉树搜索树中的搜索
利用二叉搜索树特性,将搜索复杂度降为logn
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if root is None:
return None
elif val == root.val:
return root
elif val > root.val:
return self.searchBST(root.right, val)
elif val < root.val:
return self.searchBST(root.left, val)
LeetCode230题 二叉树搜索树中第k小的元素
利用中序遍历有序性特点,记录中序遍历过的节点数,满足k次就停止遍历,记录结果
如果想实现logn的时间复杂度算法,每个节点需要记录自己的排名,这样就可以利用二叉搜索树特性解题
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
self.res = None
self.num = 0
self.traversal(root, k)
return self.res
def traversal(self, root, k):
if not root:
return
self.traversal(root.left, k)
if self.num == k:
return
self.res = root.val
self.num += 1
self.traversal(root.right, k)
LeetCode501题 二叉搜索树中的众数
利用中序遍历有序性特点
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def findMode(self, root: Optional[TreeNode]) -> List[int]:
self.res = []
self.cur_count = 0
self.last_val = float('-inf')
self.max_count = float('-inf')
self.traversal(root)
return self.res
def traversal(self, node):
if node is None:
return
self.traversal(node.left)
if node.val == self.last_val:
self.cur_count += 1
else:
self.cur_count = 1
self.last_val = node.val
if self.cur_count > self.max_count:
self.max_count = self.cur_count
self.res = [node.val]
elif self.cur_count == self.max_count:
self.res.append(node.val)
self.traversal(node.right)
LeetCode530题 二叉搜索树的最小绝对差
利用中序遍历有序性特点,只需要计算相邻元素的差值即可
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
self.pre = None
self.res = float('inf')
self.traversal(root)
return self.res
def traversal(self, root):
if root is None:
return
self.traversal(root.left)
if self.pre is not None:
self.res = min(self.res, root.val - self.pre)
self.pre = root.val
self.traversal(root.right)
LeetCode538题 把二叉树搜索树转换为累加树
利用中序遍历有序性特点,按照“右中左”遍历顺序遍历,记录累加和,将累加和,将累加和与当前节点值相加即可
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
self.pre_sum = 0
self.traversal(root)
return root
def traversal(self, root):
if not root:
return
self.traversal(root.right)
root.val += self.pre_sum
self.pre_sum = root.val
self.traversal(root.left)
return
判断合法性、增、删问题
LeetCode98题 验证二叉搜索树
通过使用递归函数,增加函数参数列表,在参数中携带额外信息,将二叉搜索树的约束传递给子树的所有节点。(递归函数增加参数,可以让信息自顶向下传递;递归函数带返回值,可以让信息自底向上传递)
遍历思路-递归法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
return self.traversal(root, None, None)
def traversal(self, root, min_node, max_node):
# min_node表示以root为根的子树节点值下限,max_node表示以root为根的子树节点值上限,否则就不符合条件
if not root:
return True
if min_node and root.val <= min_node.val:
return False
if max_node and root.val >= max_node.val:
return False
left = self.traversal(root.left, min_node, root)
right = self.traversal(root.right, root, max_node)
return left and right
LeetCode450题 删除二叉搜索树中的节点
分解思路-递归法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
if not root:
return
if root.val < key:
root.right = self.deleteNode(root.right, key)
elif root.val > key:
root.left = self.deleteNode(root.left, key)
else:
if not root.left:
root = root.right
elif not root.right:
root = root.left
else:
cur = root.left
while cur.right:
cur = cur.right
cur.right = root.right
root = root.left
return root
LeetCode669题 修剪二叉搜索树
分解思路-递归法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
if not root:
return
if root.val < low:
return self.trimBST(root.right, low, high)
elif root.val > high:
return self.trimBST(root.left, low, high)
else:
root.left = self.trimBST(root.left, low, high)
root.right = self.trimBST(root.right, low, high)
return root
LeetCode701题 二叉搜索树中的插入操作
分解思路-递归法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if not root:
return TreeNode(val=val)
if root.val > val:
root.left = self.insertIntoBST(root.left, val)
else:
root.right = self.insertIntoBST(root.right, val)
return root
LeetCode1373题 二叉搜索子树的最大键值和
在后序位置自底向上判断是否是二叉搜索子树、返回子树节点值的和。在遍历过程中遇到符合条件的子树时,更新结果(本题和“验证二叉搜索树”有点类似,但“验证二叉搜索树”解法采用自顶向下传递信息的方式判断)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxSumBST(self, root: Optional[TreeNode]) -> int:
self.res = 0
self.traversal(root)
return self.res
def traversal(self, root):
# 返回以root为根节点子树的节点和、子树最小值、最大值,若root不是二叉搜索树全部返回None
if not root:
return 0, float('inf'), float('-inf')
left_sum, left_min, left_max = self.traversal(root.left)
right_sum, right_min, right_max = self.traversal(root.right)
if left_sum is not None and right_sum is not None and root.val > left_max and root.val < right_min:
r = left_sum + right_sum + root.val
self.res = max(self.res, r)
return r, min(left_min, root.val), max(right_max, root.val)
else:
return None, None, None
构造问题
LeetCode108题 将有序数组转换为二叉搜索树
分解思路-递归法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
if not nums:
return
mid = len(nums) // 2
root = TreeNode(val=nums[mid])
root.left = self.sortedArrayToBST(nums[:mid])
root.right = self.sortedArrayToBST(nums[mid + 1:])
return root
LeetCode96题 不同的二叉搜索树
动态规划
class Solution:
def numTrees(self, n: int) -> int:
dp = [1] * (n + 1)
for i in range(2, n + 1):
r = 0
for j in range(1, i + 1):
r += dp[j - 1] * dp[i - j]
dp[i] = r
return dp[n]
LeetCode95题 不同的二叉搜索树II
递归函数返回值设计为 以[start:end]区间中的数组成的二叉搜索树根节点,在后序位置组合左右子树的根节点 作为不同的二叉搜索树结果
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def generateTrees(self, n: int) -> List[Optional[TreeNode]]:
return self.traversal(1, n)
def traversal(self, start, end):
# 返回以[start:end]区间中的数组成的二叉搜索树根节点
if start > end:
return [None]
res = []
for i in range(start, end + 1):
left = self.traversal(start, i - 1)
right = self.traversal(i + 1, end)
for j in left:
for k in right:
root = TreeNode(val=i)
root.left = j
root.right = k
res.append(root)
return res