1. 题目
- 给定一个二叉树,判断其是否是一个有效的二叉搜索树:https://leetcode-cn.com/problems/validate-binary-search-tree/
- 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/
2. 基本知识
树、二叉树、二叉搜索树
2.1 树
由N个点构成的一种数据结构,有一个根节点和多层的子节点组成,连接的顺序都是从根节点指向孩子节点。每一个子节点都只有一个前驱节点,但一个父节点可能有多个孩子节点。
2.2 二叉树
二叉树是树的一种,它的特点是每一个节点最多只有两个子节点。
2.3 二叉搜索树
它是二叉树的一种,又叫有序二叉树。它是指一棵空树或者有以下性质的二叉树。增删查的时机复杂度为O(logn)
- 左子树上所有节点的值均小于它的根节点的值
- 右子树上所有的节点的值均大于它的根节点的值
- 左右子树也分别为小二叉搜索树
3. 算法题解题
3.1 给定一个二叉树,判断其是否是一个有效的二叉搜索树
假设存在链表 1 → 2 → 3 → Ø,我们想要把它改成 Ø ← 1 ← 2 ← 3。把每个节点的next指向它的前一个节点即可。
解法1:中序遍历法
左节点-父节点-右节点,这个遍历顺序,则判断前一个节点的值比后一个节点的值小即可。
时间复杂度为O(n),空间复杂度也为O(n)
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public boolean isValidBST(TreeNode root) {
Stack<TreeNode> stack = new Stack<TreeNode>();
if (root == null) {
return true;
}
double inorder = -Double.MAX_VALUE;
while (!stack.isEmpty() || root != null) {
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.pop();
if (root.val < inorder) {
return false;
}
inorder = root.val;
root = root.right;
}
return false;
}
解法2: 递归
分别递归左右子树,一直递归找到左子树的最大值,右子树的最小值,然后把返回的值进行比较,左节点最大值小于根节点,小于右节点最小值。
public boolean isValidBST(TreeNode root) {
return validHelper(root ,null, null);
}
public boolean validHelper(TreeNode root, Integer min, Integer max){
if (root == null) {
return true;
}
Integer tempVal = root.val;
// 当前值和最小值比较
if (min != null && tempVal <= min) return false;
// 当前值和最大值比较
if (max != null && tempVal >= max) return false;
//递归循环
//左子树,最大值是当前节点值
if (!validHelper(root.left, min, tempVal)) return false;
//右子树,最小值是当前节点值
if(!validHelper(root.right, tempVal, max)) return false;
return true;
}
3.2 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先
tips:自己也可以是自己的祖先节点
解法1: 递归法
从根节点开始遍历,如果找到其中一个节点,则 temp 标记为1,如果找到其中一个则认为该分支找到了。继续遍历另一个分支,直到left、right、temp其中两个为1时,则认为找到了公共祖先。
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
recurseTree(root, p, q);
return result;
}
TreeNode result;
private boolean recurseTree(TreeNode currentNode, TreeNode p, TreeNode q) {
if (currentNode == null) {
return false;
}
int left = recurseTree(currentNode.left, p, q) ? 1 : 0;
int right = recurseTree(currentNode.right, p, q) ? 1 : 0;
int temp= 0;
if (currentNode == p || currentNode == q) {
temp = 1;
}
if (temp + left + right == 2) {
result = currentNode;
}
if (temp + left + right > 0) {
return true;
}
return false;
}
4. Tips
一个可以免费上传图片,并分享链接的网站
https://sm.ms/
点击,并上传照片。
然后,分享链接即可。