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

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

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

class Solution {
public:
    void inorder(TreeNode* root,vector& v){
        if(root == nullptr) return;
        if(root->left) inorder(root->left,v);
        v.push_back(root->val);
        if(root->right) inorder(root->right,v);
        return;
    }
    int getMinimumDifference(TreeNode* root) {
        vector v;
        inorder(root,v);
        int ans = INT_MAX;
        for(int i = 0; i < v.size() - 1; ++i){
            int dif = abs(v[i] - v[i+1]);
            if(dif < ans){
                ans = dif;
            }
        }
        return ans;
    }
};

501.二叉搜索树中的众数

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

class Solution {
public:
    void inorder(TreeNode* root, vector& v){
        if(root == nullptr) return;
        if(root->left) inorder(root->left, v);
        v.push_back(root->val);
        if(root->right) inorder(root->right, v);
    }
    vector findMode(TreeNode* root) {
        vector v;
        inorder(root,v);
        vector ans;
        int num = 0;
        int count = 0;
        for(int i = 1; i <= v.size(); ++i){
            if(i < v.size() &&v[i] == v[i-1]){
                count++;
            }else{
                if(count > num){
                    ans.clear();
                    ans.push_back(v[i-1]);
                    num = count;
                }else if(count == num){
                    
                    ans.push_back(v[i-1]);
                }
                count = 0;
            }
        }
        return ans;
    }
};

//map统计元素频率然后用vector排序的方法
//没有用到搜索二叉树的特性
class Solution {
private:

void searchBST(TreeNode* cur, unordered_map& map) { // 前序遍历
    if (cur == NULL) return ;
    map[cur->val]++; // 统计元素频率
    searchBST(cur->left, map);
    searchBST(cur->right, map);
    return ;
}
bool static cmp (const pair& a, const pair& b) {
    return a.second > b.second;
}
public:
    vector findMode(TreeNode* root) {
        unordered_map map; // key:元素,value:出现频率
        vector result;
        if (root == NULL) return result;
        searchBST(root, map);
        vector> vec(map.begin(), map.end());
        sort(vec.begin(), vec.end(), cmp); // 给频率排个序
        result.push_back(vec[0].first);
        for (int i = 1; i < vec.size(); i++) {
            // 取最高的放到result数组中
            if (vec[i].second == vec[0].second) result.push_back(vec[i].first);
            else break;
        }
        return result;
    }
};


//双指针法(pre和cur),一次遍历求众数,也就是不开辟额外中序数组的方法
class Solution {
private:
    int maxCount = 0; // 最大频率
    int count = 0; // 统计频率
    TreeNode* pre = NULL;
    vector result;
    void searchBST(TreeNode* cur) {
        if (cur == NULL) return ;

        searchBST(cur->left);       // 左
                                    // 中
        if (pre == NULL) { // 第一个节点
            count = 1;
        } else if (pre->val == cur->val) { // 与前一个节点数值相同
            count++;
        } else { // 与前一个节点数值不同
            count = 1;
        }
        pre = cur; // 更新上一个节点

        if (count == maxCount) { // 如果和最大值相同,放进result中
            result.push_back(cur->val);
        }

        if (count > maxCount) { // 如果计数大于最大值频率
            maxCount = count;   // 更新最大频率
            result.clear();     // 很关键的一步,不要忘记清空result,之前result里的元素都失效了
            result.push_back(cur->val);
        }

        searchBST(cur->right);      // 右
        return ;
    }

public:
    vector findMode(TreeNode* root) {
        count = 0;
        maxCount = 0;
        TreeNode* pre = NULL; // 记录前一个节点
        result.clear();

        searchBST(root);
        return result;
    }
};

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

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

//找两个节点的路径,然后找到路径上最后一个相同的的节点
class Solution {
public:
    vector v_ans;
    void find_v(TreeNode* root,int val,vector& v){
        v.push_back(root);
        if(root == nullptr) return;
        if(root->val == val){
            v_ans.assign(v.begin(),v.end());
            return;
        }
        if(root->left){
            find_v(root->left,val,v);
            v.pop_back();
        }
        if(root->right){
            find_v(root->right,val,v);
            v.pop_back();
        }
        return;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        vector v;
        v.clear();
        v_ans.clear();
        find_v(root,p->val,v);
        vector v_p = v_ans;
        v.clear(); 
        v_ans.clear();
        find_v(root,q->val,v);
        vector v_q = v_ans;    
        TreeNode* ans = nullptr;
        for(int i = 0, j =0 ; i < v_p.size() && j < v_q.size(); ++i,++j){
            if(v_p[i] != nullptr && v_p[i] == v_q[j]) {
                ans = v_p[i]; 
            }
        }
        return ans;
    }
};

//后序遍历寻找公共节点
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == nullptr) return root;
        if(root == p || root == q) return root;
        TreeNode* left = lowestCommonAncestor(root->left,p,q);
        TreeNode* right = lowestCommonAncestor(root->right,p,q);
        if(left != nullptr && right != nullptr) return root;
        else if(left == nullptr && right != nullptr) return right;
        else if(left != nullptr && right == nullptr) return left;
        else return nullptr;

    }        
};

总结

题型:二叉搜索树,二叉树的最近公共祖先(后序遍历的处理)

技巧:二叉搜索树和中序遍历结合,二叉搜索树中的双指针

//数组的清空
v.clear()
//数组赋给另一个数组
v2.assign(v1.begin(),v1.end())

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