LeetCode 第二十一天

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

注意掌握中序遍历的迭代写法。

class Solution {
public:
    int preValue = -1;
    int MinAbs = INT_MAX;
    void traversal(TreeNode* root){
        // 第一次写出新的递归题目 耶耶耶
        if (root == nullptr) return;
        traversal(root->left);
        // 上一章卡尔给出的好方法,如果第一次直接跳过,否则找到更小的值,用全局变量记录
        if (preValue != -1 && root->val - preValue < MinAbs){
            MinAbs = root->val - preValue;
        }
        preValue = root->val;
        traversal(root->right);
    }
    int getMinimumDifference(TreeNode* root) {
        // 递归写法
        // traversal(root);
        // return MinAbs;
        // 迭代写法 (中序遍历加一个当前节点-前一个结点的遍历)
        stack<TreeNode*> st;
        // 当前节点 
        TreeNode* cur = root;
        // 前一个结点
        TreeNode* pre = nullptr;
        int res = INT_MAX;
        while (cur != nullptr || !st.empty()){
            // 只要左边不为空,一直遍历到底
            if (cur){
                st.push(cur);
                cur = cur->left;
            }
            else{
                // 取出栈顶元素
                cur = st.top();
                st.pop();
                // 如果不是第一个节点,并且满足较小值比较
                if (pre != nullptr && cur->val - pre->val < res){
                    res = cur->val - pre->val;
                }
                pre = cur;
                // 向右去遍历
                cur = cur->right;
            }
        }
        return res;
    }
};

501. 二叉搜索树中的众数

这题运用了许多的全局变量,解决了参数传递复杂的问题,在解题的过程中不失为一种好方法。

class Solution {
public:
// 全局大法好
    int count = 1;
    int MaxCount = 1;
    TreeNode* pre = nullptr;
    vector<int> res;
    void traversal(TreeNode* root){
        // 对本节点处理,如果为空,直接返回
        if (root == nullptr){
            return;
        }
        // 左
        traversal(root->left);
        // 中
        if (pre == nullptr){
            count = 1;
        }
        else if (pre->val == root->val){
            count++;
        }
        // root已经不等于前一个了,该洗牌了
        else{
            count = 1;
        }
        pre = root;
        // 大胆放心的放进去吧,反正前面的结果已成定局,后续如果还有更大的,先清空后加入
        if (count == MaxCount){
            res.push_back(root->val);
        }
        if (count > MaxCount){
            MaxCount = count;
            res.clear();//关键清空步骤
            res.push_back(root->val);
        }
        traversal(root->right);
    }
    vector<int> findMode(TreeNode* root) {
        traversal(root);
        return res;
    }
};

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

这题在没看题解之前是属于很难的题目,看完题解感觉能理解。递归采用有返回值的后序遍历递归,每次返回一个节点或者空值。开始判断如果根为空则返回空,如果遍历到p q节点,则提前返回。采用left和right变量存储每一层的返回值,如果左右子树均返回非空,则设法将本层节点一直返回到顶;否则返回不空的一边;否则返回null。这样就可以包含两种可能存在的情况。

class Solution {
public:
    TreeNode* traversal(TreeNode* root, TreeNode* p, TreeNode* q){
        // 这题卡哥讲的太牛逼了,我觉得也理解的很好
        // root为空终止,有返回值,返回root即null
        if (root == nullptr) return root;
        // 遍历过程中找到p节点或者q节点,直接提前返回
        if (root == p || root == q) return root;
        // 后续遍历,记录下返回的东西
        TreeNode* left = traversal(root->left, p, q);
        TreeNode* right = traversal(root->right, p ,q);
        // 如果当前节点root两边的返回值不为空,证明这个节点为p q的最近公共祖先
        if (left && right){
            return root;
        }
        // 如果只有一边不为空,返回不为空的一边
        else if (!left && right){
            return right;
        }
        else if (left && !right){
            return left;
        }
        // 否则返回null
        else return nullptr;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        return traversal(root, p, q);
    }
};

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