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

Leetcode 530.二叉搜索树的最小绝对差
思路分析:
本题可按中序遍历把二叉搜索树的值保存到数组中,然后遍历数组找到差值的最小值。此解法虽然容易理解,但不提倡。可以在中序遍历二叉搜索树时就处理出结果。可以保存上一帧的节点pre_node, 递归的单层逻辑里可以判断root->val和pre_node->val的差值,如果小于min_diff则更新min_diff,最后返回min_diff.

代码实现:

class Solution {
public:
    int getMinimumDifference(TreeNode* root) {
        if (root==nullptr) return 0;
        travesal(root);
        return min_diff;
    }

private:
    TreeNode* pre_node = nullptr;
    int min_diff = INT_MAX;

    void travesal(TreeNode* root) {
        if (root == nullptr) return;
        travesal(root->left);
        if (pre_node != nullptr && root->val - pre_node->val < min_diff) {
            min_diff = root->val - pre_node->val;
        }
        pre_node = root;
        travesal(root->right);
    }
};

Leetcode 501.二叉搜索树中的众数
思路分析:
本题的直观思路是中序遍历将二叉搜索树的元素放入unordered_map中,并统计每个元素出现的次数,最后遍历unordered_map,找到出现频率最高的元素。见方法1.

还有进阶的解法,不适用unordered_map,中序遍历,单层逻辑里就找出当前元素出现的次数currFreq,然后找到出现频率最高的次数和对应的元素。最后返回result.见方法2.

代码实现:

class Solution {
public:
    vector<int> findMode(TreeNode* root) {
        vector<int> result;
        if (!root) return result;
        traverse(root);
        int maxFreq = 0;
        for (const auto &entry : frequency) {
            if (entry.second == maxFreq) {
                result.push_back(entry.first);
            } else if (entry.second > maxFreq) {
                maxFreq = entry.second;
                result = {entry.first};
            }
        }
        return result;
    }

private:
    unordered_map<int, int> frequency;
    void traverse(TreeNode* node) {
        if (node == nullptr) return;
        traverse(node->left);
        frequency[node->val]++;
        traverse(node->right);
    }
};

进阶:不使用额外的空间版本

class Solution {
public:
    vector<int> findMode(TreeNode* root) {
        vector<int> result;
        if (!root) return result;

        int prev = INT_MIN;
        int maxFreq = 0, currFreq = 1;
        
        traverse(root, prev, maxFreq, currFreq, result);
        return result;
    }

private:
    void traverse(TreeNode* node, int& prev, int& maxFreq, int& currFreq, vector<int>& result) {
        if (node == nullptr) return;
        
        traverse(node->left, prev, maxFreq, currFreq, result);
        
        if (node->val == prev) {
            currFreq++;
        } else {
            currFreq = 1;
        }
        
        if (currFreq > maxFreq) {
            result.clear();
            maxFreq = currFreq;
            result.push_back(node->val);
        } else if (currFreq == maxFreq) {
            result.push_back(node->val);
        }
        
        prev = node->val;
        
        traverse(node->right, prev, maxFreq, currFreq, result);
    }
};

Leetcode 236. 二叉树的最近公共祖先
思路分析:
首先注意题目提示,所有Node.val互不相同,p!=q,p和q均存在于给定的二叉树中。找祖先问题适合自底向上遍历,由此很好想到用后序遍历,用递归法较易实现。
本题需要遍历整棵树才能找到所有可能pq的最近公共祖先,因此,递归函数是需要有返回值的。递归函数的结束条件是root节点为p或q节点,或root为空节点。递归的单层逻辑是:1.如果左右节点都不为空,则该root就是最近公共节点,返回root;2.如果左节点为空,右节点不为空,则返回右节点;3.如果左节点不为空,右节点为空,则返回左节点;4.如果左右节点都为空,则返回空节点。注意2和3中之所以返回的是左节点或右节点,而不是root节点,是因为这种情况下,root一定不是最近的公共祖先,最近的公共祖先在左右节点中产生。

代码实现:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root==p || root==q || root==nullptr)
            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;
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值