Overview
二叉树结构体定义
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
求二叉搜索树中最小的任意两个节点的值
530. Minimum Absolute Difference in BST
和 783. Minimum Distance Between BST Nodes 重复。
783. Minimum Distance Between BST Nodes
Solution:
除了把所有值都取出来,想不到有什么更好的办法。因为是搜索二叉树,所以使用中序遍历的方式取值。
class Solution:
def recursive_inorder_traversal(self, root):
[...code from 94...]
def min_diff_in_BST(self, root):
vals = self.recursive_inorder_traversal(root)
for i in range(1, len(vals)):
vals[i-1] = vals[i] - vals[i-1]
vals.pop()
return min(vals)
def minDiffInBST(self, root: TreeNode) -> int:
return self.min_diff_in_BST(root)
98. Validate Binary Search Tree – 检查给定树是否是二叉搜索树
Solution:
关键在于确保:
- 当前结点下的左子树中的最大值必须要小于当前结点值
- 当前结点下的右子树中的最小值必须要大于当前结点值
class Solution:
def is_valid_BST(self, root):
if root is None:
raise RuntimeError("can't pass NoneType as paremter")
_max = root.val
_min = root.val
if root.left:
ret = self.is_valid_BST(root.left)
if ret is False:
return False
if ret[1] < root.val:
_min = ret[0]
else:
return False
if root.right:
ret = self.is_valid_BST(root.right)
if ret is False:
return False
if ret[0] > root.val:
_max = ret[1]
else:
return False
return _min, _max
def isValidBST(self, root: TreeNode) -> bool:
if root is None:
return True
return self.is_valid_BST(root) is not False
700. Search in a Binary Search Tree - 实现二叉搜索树的“搜索”功能
Solution:
class Solution:
def search_bst(self, root, key):
if root is None:
return None
if key < root.val:
return self.search_bst(root.left, key)
if key > root.val:
return self.search_bst(root.right, key)
return root
def searchBST(self, root: TreeNode, val: int) -> TreeNode:
return self.search_bst(root, val)
938. Range Sum of BST
Given the root
node of a binary search tree, return the sum of values of all nodes with value between L
and R
(inclusive).
The binary search tree is guaranteed to have unique values.
Solution:
class Solution:
def tree_sum(self, root):
if root is None:
return 0
ret = root.val
ret += self.tree_sum(root.left)
ret += self.tree_sum(root.right)
return ret
def greater_than_sum(self, root, L: int) -> int:
if root.val == L:
return root.val + self.tree_sum(root.right)
if root.val < L:
return self.greater_than_sum(root.right, L)
if root.val > L:
ret = root.val
ret += self.tree_sum(root.right)
ret += self.greater_than_sum(root.left, L)
return ret
def less_than_sum(self, root, R: int) -> int:
if root.val == R:
return root.val + self.tree_sum(root.left)
if root.val > R:
return self.less_than_sum(root.left, R)
if root.val < R:
ret = root.val
ret += self.tree_sum(root.left)
ret += self.less_than_sum(root.right, R)
return ret
def range_sum(self, root, L: int, R: int) -> int:
if root.val < L:
return self.range_sum(root.right, L, R)
if root.val > R:
return self.range_sum(root.left, L, R)
# now, root in the middle of [L, R]
ret = root.val
if L < root.val < R:
ret += self.greater_than_sum(root.left, L)
ret += self.less_than_sum(root.right, R)
elif root.val == L:
ret += self.less_than_sum(root.right, R)
else:
ret += self.greater_than_sum(root.left, L)
return ret
def rangeSumBST(self, root: TreeNode, L: int, R: int) -> int:
return self.range_sum(root, L, R)
230. Kth Smallest Element in a BST
Given a binary search tree, write a function kthSmallest
to find the kth smallest element in it.
Note:
You may assume k is always valid, 1 ≤ k ≤ BST’s total elements.
Example 1:
Input: root = [3,1,4,null,2], k = 1
3 / \ 1 4 \ 2
Output: 1
Example 2:
Input: root = [5,3,6,2,4,null,null,1], k = 3
5 / \ 3 6 / \ 2 4 / 1
Output: 3
Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?
Solution:
class FoundException(Exception):
pass
class Solution:
def recursive(self, root, k):
new_key = k
if root.left:
new_key = self.recursive(root.left, k)
# end, i am the smallest of (sub-)tree
if new_key == 1:
raise FoundException(root.val)
elif root.right:
new_key = self.recursive(root.right, new_key - 1)
return new_key
else:
return new_key - 1
def kthSmallest(self, root: TreeNode, k: int) -> int:
try:
self.recursive(root, k)
except FoundException as err:
return int(str(err))
虽然知道这种解法效率相对是比较低的 ,应该有更好的解法(注意到题目的 “Follow up”);但是一时想不出来,所以还是先解决掉再说。这个问题应该还算有些意思,所以后面看看 Solution 之后再用新Solution解一遍。
653. Two Sum IV - Input is a BST
Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target.
Example 1:
Input:
5
/ \
3 6
/ \ \
2 4 7
Target = 9
Output: True
Example 2:
Input:
5
/ \
3 6
/ \ \
2 4 7
Target = 28
Output: False
Solution:
class Solution:
def _lnr(self, root) -> list:
if root is None:
return []
ret = []
ret.extend(self._lnr(root.left))
ret.append(root.val)
ret.extend(self._lnr(root.right))
return ret
def findTarget(self, root: TreeNode, k: int) -> bool:
arr = self._lnr(root)
if len(arr) <= 1:
return False
l = 0
r = len(arr) - 1
while l < r:
sum_ = arr[l] + arr[r]
if sum_ > k:
r -= 1
elif sum_ < k:
l += 1
else: # sum_ == k
return True
return False
submit:
其中使用了中序遍历获得排序的数组。
然后从数组两头移动得到相加等于 target
的“下标”(不过不需要返回下标,只需要返回是否存在相加可以等于 target
的两个值的结论即可)。