LeetCode | C++ 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

目录

  • 530.二叉搜索树的最小绝对差
    • 利用双指针法 按找二叉树搜索顺序 中序遍历 找其最小差值
    • 迭代法-利用中序遍历
  • 501.二叉搜索树中的众数
    • 普通二叉树直接遍历map统计排序
    • 中序遍历-分两步-统计最大次数-再找对应次数的值
    • 中序遍历-优化-将以上两步合并为一步
  • 236. 二叉树的最近公共祖先

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

利用双指针法 按找二叉树搜索顺序 中序遍历 找其最小差值

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

迭代法-利用中序遍历

class Solution {
public:
    
    int getMinimumDifference(TreeNode* root) {
        TreeNode* node = root;
        stack<TreeNode*> stack1;
        int min = INT_MAX;
        int pre = -1;
        while (node != NULL || !stack1.empty()) {
            if (node != NULL) {
                stack1.push(node);
                node = node->left;
            } else {
                node = stack1.top();
                stack1.pop();
                if (pre >= 0 && (node->val - pre) < min) {
                    min = node->val - pre;
                } 
                pre = node->val;
                node = node->right;
            }
        }
        return min;
    }
};

501.二叉搜索树中的众数

普通二叉树直接遍历map统计排序

第一,如果不是搜索树,只是普通的二叉树, 就直接进行遍历,用map对频率进行统计,并进行排序

class Solution {
public:
    bool static cmp(const pair<int, int>& a, const pair<int, int>& b) {
        return a.second > b.second;
    }
    unordered_map<int, int> map1;
    vector<int> findMode(TreeNode* root) {
        vector<int> result;
        traversal(root);
        vector<pair<int, int>> vec(map1.begin(), map1.end());
        sort(vec.begin(), vec.end(), cmp);
        result.push_back(vec[0].first);

        for (int i = 1; i < vec.size(); i++) {
            if (vec[i].second == vec[0].second) result.push_back(vec[i].first);
            else break;
        }
        return result;

    }
    void traversal(TreeNode* node) {
        if (node == NULL) return;
        traversal(node->left);
        map1[node->val]++;
        traversal(node->right);
    }
};

中序遍历-分两步-统计最大次数-再找对应次数的值

利用二叉搜索树的特性 中序遍历
首先分两步:第一步 记录最大次数
第二步: 找到与最大次数相同的次数的值

class Solution {
public:
    int maxCount = 0;
    vector<int> result;
    vector<int> findMode(TreeNode* root) {  
        traversal(root);
        cout << maxCount;
        traversal1(root);
        return result;
    }
    TreeNode* pre = NULL;
    int tmpCount = 1;
    void traversal(TreeNode* node) {
        if (node == NULL) return;
        traversal(node->left);

        if (pre != NULL && node->val == pre->val) tmpCount++;
        else tmpCount = 1;
        pre = node;
        if (tmpCount > maxCount) maxCount = tmpCount;

        traversal(node->right);
    }

    TreeNode* pre1 = NULL;
    int Count = 1;
    void traversal1(TreeNode* node) {
        if (node == NULL) return;
        traversal1(node->left); 

        if (pre1 != NULL && node->val == pre1->val) Count++;
        else Count = 1;
        pre1 = node;
        if (Count == maxCount) result.push_back(node->val);
        traversal1(node->right);
    }
};

中序遍历-优化-将以上两步合并为一步

class Solution {
public:
    // 以上两步可以利用一个小技巧 只需要一次遍历即可
    int maxCount = 1;
    int tmpCount = 1;
    TreeNode* pre;
    vector<int> result;
    vector<int> findMode(TreeNode* root) {  
        traversal(root);
        return result;
    } 
    void traversal(TreeNode* node) {
        if (node == NULL) return;
        traversal(node->left);

        if (pre != NULL && pre->val == node->val) tmpCount++;
        else tmpCount = 1;
        pre = node;
        
        if (tmpCount == maxCount) {
            result.push_back(node->val);
        } else if (tmpCount > maxCount) {
            maxCount = tmpCount;
            result.clear();
            result.push_back(node->val);
        } else;
        traversal(node->right);
    }
};

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

思路:如果二叉树的一个结点中左子树 含有 p , 右子树含有q, 则一直往上返回

二叉树遍历 都是从根节点 从上 往下去遍历, 从下往上 只能通过回溯

所以该题 只能用 后序遍历 左 右 中, 回溯的 过程 就是中, 中 才是我们的处理逻辑。

判断左子树有没有 出现p , 出现就往上返回, 右子树有没有出现q, 出现就往上返回, 最后判断中,若左右都不为空,即为 最近公共祖先。

当p q 其中一个 本身就为 最近公共祖先时,这种情况以及被包含着 上面了, 当遇到 最近公共祖先时,就返回了,就不忘下遍历了。

class Solution {
public:
    TreeNode* result = NULL;
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root == NULL) return NULL;
        if (root == p || root == q) 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;
        if (left != NULL && right == NULL) return left;
        return NULL;
    }
};

你可能感兴趣的:(#,C++,c++,leetcode,算法)