【代码随想录】刷题Day21

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

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

首先对于单个节点而言,其最小绝对值有两个可能

一是根节点和左节点的最右节点绝对值

二是根节点和右节点的最左节点绝对值

其实这俩条件的实现就是我们代码的关键,不过这题和二叉搜索树的判断殊途同归,其实都是分别访问了左右节点的最右最左节点。那么写起来就简单了,无非要更新一下最小值。

class Solution {
public:
    void _getMiniR(TreeNode* root,int& min)
    {
        if(root==nullptr)
            return;
        int tmp;
        if(root->left)
        {
            TreeNode* left = root->left;
            while(left)
            {
                tmp = abs(left->val-root->val);
                if(tmpright;
            }
        }
        if(root->right)
        {
            TreeNode* right = root->right;
            while(right)
            {
                tmp = abs(right->val-root->val);
                if(tmpleft;
            }
        }
        _getMiniR(root->left,min);
        _getMiniR(root->right,min);
    }
    int getMinimumDifference(TreeNode* root) {
        int min = 100000;
        _getMiniR(root,min);
        return min;
    }
};

2.二叉搜索树的众数

501. 二叉搜索树中的众数

我们知道哈希表的map能够统计次数,所以递归+map应该就能实现对二叉搜索树的查找

1.在外面定义一个map,引用传入递归函数,将根节点的数统计到map中,随后左右递归

2.我们先要知道哪个数是最大的,所以先要有一个变量来存储遍历map后出现次数的最大值,当然此时我们要比较的是maxnum和map元素的second。

3.找到对应的maxnum后,我们再次遍历,将second和maxnum一样的元素,其对应的first传入到vector中

lass Solution {
public:
    void _findModeR(TreeNode* root,unordered_map& um)
    {
        if(root==nullptr)
            return;
        um[root->val]++;
        _findModeR(root->left,um);
        _findModeR(root->right,um);
    }
    vector findMode(TreeNode* root) {
        vector ret;
        int num;
        unordered_map um;
        _findModeR(root,um);
        int maxnum = 0;
        for(auto& e:um)
        {
            if(e.second>maxnum)
                maxnum=e.second;
        }
        for(auto& e:um)
        {
            if(e.second==maxnum)
                ret.push_back(e.first);
        }
        return ret;
    }
};

【代码随想录】刷题Day21_第1张图片

但是这样没有什么针对性,因为按照这个函数,所有二叉树都能通过这个函数实现。而我们要知道的是二叉搜索树的中序遍历,得到的结果其实是有顺序的,从小到大。那么我们可以用这个特性来做该题。

我们先中序遍历得到顺序vector,并且在此期间,通过比较数据是否相同获得出现最多次相同数值的个数maxnum。

随后我们设置两个指针left和right,他们两个下标的距离始终保持为maxnum,所以初始的left=0,right=left+maxnum-1,使得我们可以来循环判断(循环结束的条件是right超过范围):

1.如果v[left]和v[right]不相同,说明此时的left的数据不是最大相同数,left和right都往后加一

2.如果两个相同,说明该值就是我们需要的数,push_back到ret中,随后更新left为right+1,right更新为left+maxnum-1

class Solution {
public:
    int maxnum = 0;
    int num = 0;
    int tmp = 0;
    void GetVector(TreeNode* root,vector& v)
    {
        if(root==nullptr)
            return;
        GetVector(root->left,v);
        v.push_back(root->val);
        if(tmp==root->val)
            num++;
        else
        {
            tmp=root->val;
            num = 1;
        }
        if(maxnumright,v);
    }
    vector findMode(TreeNode* root) {
        vector v;
        vector ret;
        GetVector(root,v);
        int left = 0;
        int right = left+maxnum-1;
        while(right

3.二叉树公共祖先

为了让上层节点知道下层的节点是否是p或者q,所以我们使用的遍历是后序遍历

1.如果root为空,返回空

2.如果root等于q或者p,说明此时节点是我们要返回的q或者p节点,那么我们此时要返回的是root

3.随后是后序遍历的左右递归,分别对left和right递归,并且获取由下传到上的节点

4.中间操作就是判断是否是我们要往上返回的:

如果左右都有,说明此时root就是公共祖先,那么我们返回root即可

如果右边有,左边没有,说明公共祖先在右边;或者找到了一个节点(q或者p任意一个),此时我们要返回的就是右节点

如果右边没有,左边有,其实思路是相同的,返回左节点

最后如果都不是,说明此时不是我们要的值,我们应该返回nullptr,告诉上层,下面没有找到p和q节点

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

你可能感兴趣的:(刷题,算法,数据结构,c++,leetcode,深度优先)