二叉搜索树-
简介-2
验证二叉搜索树,中等
注意:不是左子节点和右子节点需要符合,而是左子树和右子树需要符合,所以递归函数需要引入上下界
方法一,递归:
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
if not root:
return True
def fct(node, low, high):
if not node:
return True
if node.val >= high or node.val <= low:
return False
return fct(node.left,low,node.val) and fct(node.right,node.val,high)
return fct(root , -math.inf, math.inf)
方法二,中序遍历:
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
if not root:
return True
inorder = []
def dfs(node,inorder):
if not node:
return True
a = dfs(node.left,inorder)
if not a:
return False
if not inorder or node.val > inorder[-1]: # not inorder 要写在前面,否则会数组越界
inorder.append(node.val)
else:
return False
b = dfs(node.right,inorder)
return b
return dfs(root,inorder)
二叉搜索树迭代器,中等
说不清楚,看代码吧
等于说模拟了一个递归的过程
class BSTIterator:
def __init__(self, root: TreeNode):
self.stack = []
self.add_left_order(root)
def add_left_order(self,node):
while node:
self.stack.append(node)
node = node.left
def next(self) -> int:
smallestnode = self.stack.pop()
if smallestnode.right:
self.add_left_order(smallestnode.right)
return smallestnode.val
def hasNext(self) -> bool:
return len(self.stack) > 0
BST中的基本操作
二叉搜索树中的搜索,简单
递归:
class Solution:
def searchBST(self, root: TreeNode, val: int) -> TreeNode:
if not root:
return None
if root.val == val:
return root
if root.val > val:
return self.searchBST(root.left,val)
return self.searchBST(root.right ,val)
迭代:
class Solution:
def searchBST(self, root: TreeNode, val: int) -> TreeNode:
while root:
if root.val == val:
return root
if root.val > val:
root = root.left
else:
root = root.right
return None
二叉搜索树中的插入操作,中等
简单的迭代:
class Solution:
def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
if not root:
return TreeNode(val)
node = root
while node:
lastnode = node
if node.val > val:
node = node.left
else:
node = node.right
if lastnode.val > val:
lastnode.left = TreeNode(val)
else:
lastnode.right = TreeNode(val)
return root
删除二叉搜索树中的节点,中等
没搜到的不用删
官解用递归做
自己写的,嗯讨论,很长:
class Solution:
def deleteNode(self, root: TreeNode, key: int) -> TreeNode:
def connect(father,child,isleft):
if isleft:
father.left = child
else:
father.right = child
dummy = TreeNode(0,root)
node = root
lastnode = dummy
leftflag = True
while node:
if node.val == key:
break
elif node.val > key:
lastnode = node
node = node.left
leftflag = True
else:
lastnode = node
node = node.right
leftflag = False
#如果没找到值为key的节点,不用删除
if not node:
return dummy.left
if not node.left and not node.right:
connect(lastnode,None,leftflag)
elif node.left and node.right:
nextnode = node.right
nextlastnode = None
while nextnode.left:
nextlastnode = nextnode
nextnode = nextnode.left
if not nextlastnode: #补充的情况
nextnode.left = node.left
connect(lastnode,nextnode,leftflag)
return dummy.left
if not nextnode.right:
nextlastnode.left = None
else:
nextlastnode.left = nextnode.right
nextnode.left = node.left
nextnode.right = node.right
connect(lastnode,nextnode,leftflag)
elif node.left:
connect(lastnode,node.left,leftflag)
else:
connect(lastnode,node.right,leftflag)
return dummy.left
小结-3
数据流中的第K大元素,简单
维护一个k个元素的最小堆,初始为k个负无穷
用列表即可,用下标的关系来维护父子关系
class KthLargest:
def __init__(self, k: int, nums: List[int]):
self.heap = [-math.inf for _ in range(k)]
self.k = k
for item in nums:
self.add(item)
def add(self, val: int) -> int:
if val <= self.heap[0]:
return self.heap[0]
self.heap[0] = val
i,son = 0,1
while son < self.k:
if son + 1 < self.k and self.heap[son] >= self.heap[son+1]:
if val > self.heap[son+1]:
self.heap[i] = self.heap[son+1]
self.heap[son+1] = val
i = son+1
son = i*2+1
else:
break
else:
if val > self.heap[son]:
self.heap[i] = self.heap[son]
self.heap[son] = val
i = son
son = i*2+1
else:
break
return self.heap[0]
二叉搜索树的最近公共祖先,简单
很简单,利用BST的性质,从根开始搜,第一个值在两个数之间的就是最近公共祖先
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if not root:
return root
if q.val < p.val:
return self.lowestCommonAncestor(root,q,p)
node = root
while node:
if node.val > q.val:
node = node.left
elif node.val < p.val:
node = node.right
else:
return node
存在重复元素III,中等
用桶来做,时间复杂度O(n)
class Solution:
def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:
bucket = {}
depth = t+1 #用t+1作为桶的宽度
n = len(nums)
for i in range(n):
bucket_num = nums[i] // depth #放入一个桶里
if bucket_num in bucket:
return True
if bucket_num-1 in bucket and abs(bucket[bucket_num-1]-nums[i]) <= t: #查前一个桶里有没有
return True
if bucket_num+1 in bucket and abs(bucket[bucket_num+1]-nums[i]) <= t: #查后一个桶里有没有
return True
bucket[bucket_num] = nums[i]
if i >= k:
#del bucket[(nums[i-k]) // depth]
bucket.pop(nums[i-k]//depth)
return False
附录:平衡二叉搜索树-2
平衡二叉树,简单
自顶向下递归:O(n²)
class Solution:
def countdepth(self,root):
if not root:
return 0
return max(self.countdepth(root.left),self.countdepth(root.right)) + 1
def isBalanced(self, root: TreeNode) -> bool:
if not root:
return True
if abs(self.countdepth(root.left)-self.countdepth(root.right)) > 1:
return False
return self.isBalanced(root.left) and self.isBalanced(root.right)
自底向上对高度递归:O(n)
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
def height(root):
if not root:
return 0
leftheight = height(root.left)
rightheight = height(root.right)
if leftheight < 0 or rightheight < 0 or abs(leftheight-rightheight) > 1:
return -1
return max(leftheight,rightheight) + 1
return not height(root) < 0
将有序数组转换为二叉搜索树,简单
递归,自己写的代码很简洁:
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
if not nums:
return None
n = len(nums)
x = n // 2
node = TreeNode(nums[x])
node.left = self.sortedArrayToBST(nums[0:x])
node.right = self.sortedArrayToBST(nums[x+1:n])
return node