617.合并二叉树
力扣题目链接
给你两棵二叉树: root1 和 root2 。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。
输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]
解决思路
- 如果树节点为空,则用另一颗树的节点。
Java实现
class Solution_LC617 {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1 == null) {
            return root2;
        }
        if (root2 == null) {
            return root1;
        }
        int val = root1.val + root2.val;
        TreeNode root = new TreeNode(val);
        root.left = mergeTrees(root1.left, root2.left);
        root.right = mergeTrees(root1.right, root2.right);
        return root;
    }
}
700.二叉搜索树中的搜索
力扣题目地址
给定二叉搜索树(BST)的根节点 root 和一个整数值 val。
你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。
输入:root = [4,2,7,1,3], val = 2
输出:[2,1,3]
解决思路
二叉搜索树是一个有序树:
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉搜索树
- 当root的值>指定的值,从左子树上尝试获取;否则从右子树上获取
- 当root的值>指定的值,左子树上都是比root的值小的,右子树上都是比root的值大的。
Java实现
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if (root == null || root.val == val) {
            return root;
        }
        if (root.val > val) {
            return searchBST(root.left, val);
        } else {
            return searchBST(root.right, val);
        }
    }
}
98.验证二叉搜索树
力扣题目链接
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
输入:root = [2,1,3]
输出:true
解决思路
- 构建新的递归函数,不断更新上限值和下限值。
- 中序遍历,不断比较节点
- 中序遍历,构成数组比较。
Java实现
递归实现
class Solution {
    public boolean isValidBST(TreeNode root) {
        return validBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }
    private boolean validBST(TreeNode root, long lower, long upper) {
        if (root == null) {
            return true;
        }
        if (root.val <= lower || root.val >= upper) return false;
        return validBST(root.left, lower, root.val) && validBST(root.right, root.val, upper);
    }
}
中序遍历,左中右
class Solution_LC98_II {
    public boolean isValidBST(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        long inorder = Long.MIN_VALUE;
        TreeNode cur = root;
        while (!stack.isEmpty() || cur != null) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            if (cur.val <= inorder) {
                return false;
            }
            inorder = cur.val;
            cur = cur.right;
        }
        return true;
    }
}
530.二叉搜索树的最小绝对差
力扣题目链接
给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。
输入:root = [4,2,6,1,3]
输出:1
解决思路
- 因为要获取最小值,result的初始值设置为最大。
- 使用中序遍历。
Java实现
class Solution {
    public int getMinimumDifference(TreeNode root) {
        int res = Integer.MAX_VALUE;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        TreeNode pre = null;
        while (!stack.isEmpty() || cur != null) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            if (pre != null) {
                res = Math.min(cur.val - pre.val, res);
            }
            pre = cur;
            cur = cur.right;
        }
        return res;
    }
}
501.二叉搜索树中的众数
力扣题目链接
给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
- 结点左子树中所含节点的值 小于等于 当前节点的值
- 结点右子树中所含节点的值 大于等于 当前节点的值
- 左子树和右子树都是二叉搜索树
输入:root = [1,null,2,2]
输出:[2]
解题思路
- 使用中序遍历,去挨个遍历二叉树上的元素。如果当前元素和前一个元素一致,计数+1。
- 使用全局变量,记录当前元素的次数;最大的次数。
Java实现
使用递归的方式
class Solution_LC501 {
    List<Integer> answers = new ArrayList<>();
    int base, count, maxCount;
    public int[] findMode(TreeNode root) {
        dfs(root);
        int[] mode = new int[answers.size()];
        for (int i = 0; i < answers.size(); ++i) {
            mode[i] = answers.get(i);
        }
        return mode;
    }
    private void dfs(TreeNode cur) {
        if (cur == null) {
            return;
        }
        dfs(cur.left);
        caluate(cur.val);
        dfs(cur.right);
    }
    private void caluate(int val) {
        if (val == base) {
            count++;
        } else {
            count = 1;
            base = val;
        }
        if (count == maxCount) {
            answers.add(val);
        }
        if (count > maxCount) {
            maxCount = count;
            answers.clear();
            answers.add(val);
        }
    }
}
使用中序迭代
class Solution_LC501_II {
    List<Integer> answers = new ArrayList<>();
    int count, maxCount;
    public int[] findMode(TreeNode root) {
        TreeNode cur = root;
        TreeNode pre = null;
        Stack<TreeNode> stack = new Stack<>();
        while (!stack.isEmpty() || cur != null) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            if (pre == null) {
                count = 1;
            } else if (pre.val == cur.val) {
                count++;
            } else {
                count = 1;
            }
            if (count == maxCount) {
                answers.add(cur.val);
            }
            if (count > maxCount) {
                maxCount = count;
                answers.clear();
                answers.add(cur.val);
            }
            pre = cur;
            cur = cur.right;
        }
        int[] mode = new int[answers.size()];
        for (int i = 0; i < answers.size(); ++i) {
            mode[i] = answers.get(i);
        }
        return mode;
    }
}
236. 二叉树的最近公共祖先
力扣题目链接
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。
解题思路
- 如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。
- 在子树上找到p或者q,就可以了。如果p和q分别在两个子树上都可以分别找到,则当前节点是公共祖先。
Java实现
class Solution_LC236 {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) {
            return root;
        }
        //后序遍历
        TreeNode leftNode = lowestCommonAncestor(root.left, p, q);
        TreeNode rightNode = lowestCommonAncestor(root.right, p, q);
        if (leftNode == null && rightNode == null) {
            return null;
        }
        if (leftNode == null) {
            return rightNode;
        }
        if (rightNode == null) {
            return leftNode;
        }
        return root;
    }
}
235. 二叉搜索树的最近公共祖先
力扣题目链接
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6 
解释: 节点 2 和节点 8 的最近公共祖先是 6。
解题思路
- 公共祖先的节点的值的大小必须大于等于左节点,小于等于右节点。如果当前节点的值比p和q节点的值都要大,可以在左子树上继续寻找,左子树上都是比当前节点小的数据。如果当前节点的值比p和q的节点都要小的话,在右子树上寻找。
Java实现
递归方式
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root.val > p.val && root.val > q.val) {
            return lowestCommonAncestor(root.left, p, q);
        }
        if (root.val < p.val && root.val < q.val) {
            return lowestCommonAncestor(root.right, p, q);
        }
        return root;
    }
}
非递归方式
public class Solution_LC235_II {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        while (true) {
            if (root.val > p.val && root.val > q.val) {
                root = root.left;
            } else if (root.val < p.val && root.val < q.val) {
                root = root.right;
            } else {
                break;
            }
        }
        return root;
    }
}




















