代码随想录算法训练营第二十一天|530. 二叉搜索树的最小绝对差、501. 二叉搜索树中的众数、236. 二叉树的最近公共祖先。

530. 二叉搜索树的最小绝对差

题目链接:二叉搜索树的最小绝对差

题目描述
给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。

解题思路
遇到二叉搜索树就可以利用中序遍历,把二叉搜索树看成一个递增的数组,然后对数组进行处理。这样一想操作就简单了。
而此题是求最小值,因为是递增数据,所以最小值就是相邻两个节点间的差值,只需要在遍历过程中记录前一个节点,然后更新pre节点和当前节点差值的最小值即可。

代码实现
递归法

class Solution {
    TreeNode pre;// 记录上一个节点
    int res = Integer.MAX_VALUE;

    public int getMinimumDifference(TreeNode root) {
        if (root == null) {
            return 0;
        }
        traversal(root);
        return res;
    }

    // 中序遍历
    public void traversal(TreeNode node) {
        if (node == null) {
            return;
        }
        // 左遍历
        traversal(node.left);
        // 中遍历
        if (pre != null) {
            res = Math.min(res, node.val - pre.val);
        }
        pre = node;
        // 右遍历
        traversal(node.right);
    }
}

迭代法

class Solution {
    public int getMinimumDifference(TreeNode root) {
        TreeNode pre = null;
        int res = Integer.MAX_VALUE;
        if (root == null) {
            return 0;
        }
        Stack<TreeNode> sta = new Stack<>();
        TreeNode cur = root;
        while (cur != null || !sta.isEmpty()) {
            while (cur != null) {
                sta.push(cur);
                cur = cur.left;
            }
            cur = sta.pop();
            if (pre != null) {
                res = Math.min(res, cur.val - pre.val);
            }
            pre = cur;
            cur = cur.right;
        }
        return res;
    }
}

501. 二叉搜索树中的众数

题目链接:二叉搜索树中的众数

题目描述
给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
结点左子树中所含节点的值 小于等于 当前节点的值
结点右子树中所含节点的值 大于等于 当前节点的值
左子树和右子树都是二叉搜索树

解题思路
本题根据二叉搜索树,可以中序遍历,更新当前数字的计数器和最大计数,当相等时加入结果集,大于时清空结果集,更新最大计数并加入结果集中即可。

代码实现

class Solution {
    public int[] findMode(TreeNode root) {
        TreeNode pre = null;
        Stack<TreeNode> sta = new Stack<>();
        int maxCount = 0;
        int count = 0;
        List<Integer> res = new ArrayList<>();
        TreeNode cur = root;
        while (cur != null || !sta.isEmpty()) {
            while (cur != null) {
                sta.push(cur);
                cur = cur.left;
            }
            cur = sta.pop();
            if (pre == null || cur.val != pre.val) {
                count = 1;
            } else {
                count++;
            }
            if (count > maxCount) {
                maxCount = count;
                res.clear();
                res.add(cur.val);
            } else if (count == maxCount) {
                res.add(cur.val);
            }
            pre = cur;
            cur = cur.right;
        }
        int[] resInt = new int[res.size()];
        for(int i=0; i<res.size();i++){
            resInt[i]=res.get(i);
        }
        return resInt;
    }
}

236. 二叉树的最近公共祖先

题目链接:二叉树的最近公共祖先

题目描述
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

解题思路
本题解题思路参考力扣题解中的Krahets
若 root是p,q的 最近公共祖先,则只可能为以下情况之一:
1、p和q在root的子树中,且分列root的异侧(即分别在左、右子树中)
2、p=root,且q在root的左或右子树中;
3、q=root,且p 在root的左或右子树中;
则可按照这三种情况写终止条件。

代码实现

class Solution {
    public 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);
        if (left == null) {
            return right;
        }
        if (right == null) {
            return left;
        }
        return root;
    }
}

你可能感兴趣的:(算法)