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

参考

代码随想录

题目一:LeetCode 530.二叉搜索树的最小绝对差

这个题和之前的验证二叉搜索树的题一样,可以将二叉树转化为数组,然后遍历数组求差值就可以了。

class Solution {
public:
    void traversal(vector<int>& nums,TreeNode* root)
    {
        if(root == nullptr) return ;
        traversal(nums,root->left);
        nums.push_back(root->val);
        traversal(nums,root->right);
    }
    int getMinimumDifference(TreeNode* root) {
        vector<int> nums;
        traversal(nums,root);
        int min = nums[1]-nums[0];
        for(int i=1;i<nums.size()-1;i++)
            min = (min > nums[i+1] - nums[i]) ? nums[i+1] - nums[i] : min;
        return min;
    }
}

如果不使用数组,可以额外定义一个指针记录上一个节点,在遍历二叉树过程中就可以计算差值,代码如下:

class Solution {
public:
    int min = INT_MAX;
    TreeNode* pre = nullptr;
    void traversal(TreeNode* root)
    {
        if(root == nullptr) return;
        traversal(root->left);
        if(pre != nullptr)  
            min = (root->val - pre->val < min) ? (root->val - pre->val) : min;
        pre = root;
        traversal(root->right);
    }
    int getMinimumDifference(TreeNode* root) {
        traversal(root);
        return min;
    }
};

题目二:LeetCode 501.二叉搜索树中的众数

用unordered_map来统计每个数值出现的次数,然后将unordered_map放入的vector中,用sort()函数进行排序,再输出结果。这样做比较简单,但没有用到二叉搜索树的性质。

class Solution {
public:
    void traversal(TreeNode* root,unordered_map<int,int>& mp)
    {
        if(root == nullptr) return ;
        traversal(root->left,mp);
        mp[root->val]++;
        traversal(root->right,mp);
    }
    bool static comp(pair<int,int>& x,pair<int,int>& y)
    {
        return x.second > y.second;
    }
    vector<int> findMode(TreeNode* root) {
        unordered_map<int,int> mp;
        vector<int> res;
        traversal(root,mp);
        vector<pair<int,int>> vec(mp.begin(),mp.end());
        sort(vec.begin(),vec.end(),comp);
        res.push_back(vec[0].first);
        for(int i=1;i<vec.size();i++)
            if(vec[i].second == vec[0].second)  res.push_back(vec[i].first);
            else break;
        return res;   
    }
};

题目三:LeetCode 236. 二叉树的最近公共祖先

  1. 确定递归函数的参数和返回值
    参数:根节点,节点q和节点q
    返回值:如果遇到p或者q,就把q或者p返回,返回值不为空,就说明找到了q或者p
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
  1. 确定终止条件
    如果传入的根节点为空,说明已经到底了,返回空;如果根节点等于p或q,就返回p或者q。
if (root == q || root == p || root == NULL) return root;
  1. 确定单层递归逻辑
    在递归函数有返回值的情况下:如果要搜索一条边,递归函数返回值不为空的时候,立刻返回,如果搜索整个树,直接用一个变量left、right接住返回值,这个left、right后序还有逻辑处理的需要,也就是后序遍历中处理中间节点的逻辑(也是回溯)。
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);

如果left 和 right都不为空,说明此时root就是最近公共节点。这个比较好理解
如果left为空,right不为空,就返回right,说明目标节点是通过right返回的,反之亦然。

if (left == NULL && right != NULL) return right;
else if (left != NULL && right == NULL) return left;
else  { //  (left == NULL && right == NULL)
    return NULL;
}

整体代码如下:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root == q || root == p || root == NULL) return root;
        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        TreeNode* right = lowestCommonAncestor(root->right, p, q);
        if (left != NULL && right != NULL) return root;

        if (left == NULL && right != NULL) return right;
        else if (left != NULL && right == NULL) return left;
        else  { //  (left == NULL && right == NULL)
            return NULL;
        }

    }
};

你可能感兴趣的:(代码随想录训练营,leetcode,算法,数据结构)