day21 ● 530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ● 236. 二叉树的最近公共祖先

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

二叉搜索树(Binary Search Tree,简称 BST)是一种特殊的二叉树,它的每个节点都满足以下条件:

  1. 左子树上所有节点的值均小于该节点的值;
  2. 右子树上所有节点的值均大于该节点的值;
  3. 左右子树都是二叉搜索树。

因此,对于一棵二叉搜索树,中序遍历得到的结果是一个有序的数组。而本题就是要求在一个二叉搜索树中找到任意两个节点的差的绝对值的最小值。

解题思路:

  1. 对二叉搜索树进行中序遍历,得到一个有序数组。
  2. 遍历该有序数组,计算相邻两个元素的差值,找到其中最小的即可。

代码实现:

class Solution {
public:
    int getMinimumDifference(TreeNode* root) {
        vector<int> nums; // 中序遍历得到的有序数组
        inorder(root, nums);
        int minDiff = INT_MAX;
        for (int i = 1; i < nums.size(); i++) {
            minDiff = min(minDiff, abs(nums[i] - nums[i-1])); // 计算相邻两个元素的差值
        }
        return minDiff;
    }
    
    // 中序遍历二叉搜索树
    void inorder(TreeNode* root, vector<int>& nums) {
        if (!root) return;
        inorder(root->left, nums);
        nums.push_back(root->val);
        inorder(root->right, nums);
    }
};

时间复杂度:O(n),其中 n 是二叉搜索树中节点的个数。

  1. 二叉搜索树中的众数

这道题要求我们找到二叉搜索树中出现次数最多的元素。

解题思路:

  1. 对二叉搜索树进行中序遍历,得到一个有序数组。
  2. 遍历该有序数组,计算每个元素出现的次数,找到出现次数最多的元素即可。

代码实现:

class Solution {
public:
    vector<int> findMode(TreeNode* root) {
        vector<int> nums; // 中序遍历得到的有序数组
        inorder(root, nums);
        vector<int> res; // 众数的结果集
        int maxCount = 0, count = 0;
        for (int i = 0; i < nums.size(); i++) {
            count++; // 统计当前元素出现的次数
            if (i == nums.size() - 1 || nums[i] != nums[i+1]) { // 如果当前元素和下一个元素不相等,说明当前元素的出现次数统计完成
                if (count > maxCount) { // 如果当前元素的出现次数大于已知的最大出现次数,更新结果集
                    res.clear();
                    res.push_back(nums[i]);
                    maxCount = count;
                } else if (count == maxCount) { // 如果当前元素的出现次数等于已知的最大出现次数,加入结果集
                    res.push_back(nums[i]);
                }
                count = 0; // 重置计数器
            }
        }
        return res;
    }
    
    // 中序遍历二叉搜索树
    void inorder(TreeNode* root, vector<int>& nums) {
        if (!root) return;
        inorder(root->left, nums);
        nums.push_back(root->val);
        inorder(root->right, nums);
    }
};

时间复杂度:O(n),其中 n 是二叉搜索树中节点的个数。

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

这道题要求我们找到二叉树中任意两个节点的最近公共祖先。

解题思路:

我们可以采用递归的方式来解决该问题。对于当前节点,分别递归遍历其左右子树,如果左子树返回的结果不为空,右子树返回的结果也不为空,则说明当前节点为 p 和 q 的最近公共祖先;如果左子树返回的结果为空,则说明 p 和 q 只可能在右子树中,返回右子树的结果;如果右子树返回的结果为空,则说明 p 和 q 只可能在左子树中,返回左子树的结果。

代码实现:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (!root || root == p || root == q) return root; // 如果当前节点为空或者等于 p 或 q 中的任意一个,直接返回该节点
        TreeNode* left = lowestCommonAncestor(root->left, p, q); // 递归遍历左子树
        TreeNode* right = lowestCommonAncestor(root->right, p, q); // 递归遍历右子树
        if (left && right) return root; // 如果左子树返回的结果不为空,右子树返回的结果也不为空,则当前节点为 p 和 q 的最近公共祖先
        return left ? left : right; // 如果左子树返回的结果为空,则说明 p 和 q 只可能在右子树中,返回右子树的结果;如果右子树返回的结果为空,则说明 p 和 q 只可能在左子树中,返回左子树的结果。
    }
};

时间复杂度:O(n),其中 n 是二叉树中节点的个数。

你可能感兴趣的:(刷题,算法,leetcode,数据结构)