文章目录
【一】 Tree(树)
- 结构
- 代码 创建树
# python
class TreeNode:
def __init__(self, val):
self.val = val
self.left, self.right = None, None
// c++
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x):val(x), left(NULL), right(NULL) {}
}
【1.1】 Complete Binary Tree(完全二叉树)
【1.2】 Binary Search Tree(二叉搜索树)
- 左子树 上的 所有节点 的值均 小于 它的 根节点 的值
- 右子树 上的 所有节点 的值均 大于 它的 根节点 的值
- 递归的,左右子树也分别为二叉搜索树
- 查找(O ( logN ))
【1.3】 B Tree(B树,B减树,平衡多路查找树)
- 高级的 二叉平衡树,主要用于查找磁盘中的大量数据
- 若 根节点 不是 叶子节点,则至少有2棵子树
- 除 根节点 以外的所有 非叶节点 至少有 M/2 棵子树,至多有 M 个子树(M阶)
- 所有的 叶子节点都位于同一层
【1.4】 B+ Tree(B+ 树)
- 高级的 B树,比 B树 的查询性能更高
- 叶子节点包含了全部数据,拥有指针链接,同时符合左小右大的顺序
【二】 Garph(图)
- 结构
【三】 Interview(面试题)
【3.1】 LeetCode 98:Validate BST(验证二叉搜索树)
Input: [ 2, 1, 5, null, null, 2 ]
Output: true
Input: [ 5, 1, 4, null, null, 3, 6 ]
Output: false
- In-Order(中序遍历)
# python 1 (很好理解)
def isValidBST(self, root):
inorder = self.inorder(root)
return inorder == list(sorted(set(inorder)))
# 中序遍历,左,根,右
def inorder(self, root):
if root is None:
return []
return self.inorder(root.left) + [root.val] + self.inorder(root.right)
# python 2 (不太能很好的理解)
def isValidBST(self, root):
self.prev = None
return self.helper(root)
# 中序遍历,左,根,右
def helper(self, root):
if root is None:
return True
# 左
if not self.helper(root.left):
return False
# 判断当前节点和前继节点的大小
if self.prev and self.prev.val >= root.val:
return False
self.prev = root
# 右
return self.helper(root.right)
- Recursion(递归)
// java (巧妙设置了 最小值min 和 最大值max)
public boolean isValid(TreeNode root, Integer min, Integer max) {
if (root == null) return true;
// 如果当前的值比最小值还小,那就不对了
if (min != null && root.val <= min) return false;
// 如果当前的值比最大值还大,那也不对了
if (max != null && root.val >= max) return false;
// 巧妙地利用了最大值和最小值,来判断左右子树
return isValid(root.left, min, root.val) && isValid(root.right, root.val, max);
}
【3.2】 LeetCode 236,235:Lowest Common Ancestor(二叉树 / 二叉搜索树的最近公共祖先)
Input: root = [ 6, 2, 8, 0, 4, 7, 9, null, null, 3, 5 ],p = 2,q = 8
Output: 6
Input: root = [ 6, 2, 8, 0, 4, 7, 9, null, null, 3, 5 ],p = 2,q = 4
Output: 2
- Recursion(递归 - 任意的二叉树)
// java (不好理解)
TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root;
// 左子树
TreeNode left = lowestCommonAncestor(root.left, p, q);
// 右子树
TreeNode right = lowestCommonAncestor(root.right, p, q);
// 如果左子树为空,说明 p 和 q 都在右子树,返回右子树
// 如果右子树为空,说明 p 和 q 都在左子树,返回左子树
// 如果左右子树都不为空,说明分别在左右子树里,返回其 root
return left == null ? right : right == null ? left : root;
}
- Recursion(递归 - 二叉搜索树)
# python 1
def lowestCommonAncestor(self, root, p, q):
# 如果 p 和 q 都小于 root,那么说明都在左子树里
if p.val < root.val > q.val:
return self.lowestCommonAncestor(root.left, p, q)
# 如果 p 和 q 都大于 root,那么说明都在右子树里
if p.val > root.val < q.val:
return self.lowestCommonAncestor(root.right, p, q)
# 最后返回 root 就行
return root
- Unrecursion(非递归 - 二叉搜索树)
# python 2 (思路和上面一样)
def lowestCommonAncestor(self, root, p, q):
while root:
# 如果 p 和 q 都小于 root,那么说明都在左子树里
if p.val < root.val > q.val:
root = root.left
# 如果 p 和 q 都大于 root,那么说明都在右子树里
elif p.val > root.val < q.val:
root = root.right
# 最后返回 root 就行
else: return root