Day18 二叉树专项

本文介绍了三个LeetCode问题的解法,涉及二叉搜索树的操作。一是找到树中节点值的最小绝对差,通过中序遍历实现;二是寻找树中的众数,利用树的有序性优化查找;三是计算两个节点的最近公共祖先,采用递归策略解决。
摘要由CSDN通过智能技术生成

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

// 递归:中序遍历得到递增数组,然后遍历数组得到最小差值
class Solution {
 public:
  void traversal(TreeNode* root) {
    if (root == nullptr) return;

    if (root->left) traversal(root->left);

    value_vec_.push_back(root->val);

    if (root->right) traversal(root->right);
  }

  int getMinimumDifference(TreeNode* root) {
    value_vec_.clear();
    traversal(root);

    int min_diff = INT_MAX;

    for (int i = 1; i < value_vec_.size(); i++) {
      int diff = value_vec_[i] - value_vec_[i - 1];
      if (diff < min_diff) min_diff = diff;
    }

    return min_diff;
  }

 private:
  vector<int> value_vec_;
};

// 直接在中序递归遍历中得到最小差值
class Solution {
 public:
  void traversal(TreeNode* root) {
    if (root == nullptr) return;
    if (root->left) traversal(root->left);

    if (pre_ != nullptr) {
      min_diff_ = min(min_diff_, root->val - pre_->val);
    }
    pre_ = root;

    if (root->right) traversal(root->right);
  }

  int getMinimumDifference(TreeNode* root) {
    traversal(root);
    return min_diff_;
  }

 private:
  TreeNode* pre_ = nullptr;
  int min_diff_ = INT_MAX;
};

LeetCode 501. 二叉搜索树中的众数

// 中序遍历得到所有节点的访问次数,自定义比较函数对频率进行排序
// 但是没有利用到二叉搜索树的特性
class Solution {
 public:
  void traversal(TreeNode* root) {
    if (root == nullptr) return;
    if (root->left) traversal(root->left);
    count_map_[root->val]++;
    if (root->right) traversal(root->right);
  }

  vector<int> findMode(TreeNode* root) {
    traversal(root);

    vector<pair<int, int>> vec(count_map_.begin(), count_map_.end());
    sort(vec.begin(), vec.end(),
         [](const pair<int, int>& a, const pair<int, int>& b) {
           return a.second > b.second;  // 按照频率逆序排列
         });

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

 private:
  map<int, int> count_map_;  // key: val, value: frequency
};

// 利用了二叉搜索树有序的特性
class Solution {
 public:
  void traversal(TreeNode* root) {
    if (root == nullptr) return;

    if (root->left) traversal(root->left);

    // 先处理count
    if (pre_ == nullptr) {
      cur_count_ = 1;
    } else if (pre_->val == root->val) {
      cur_count_++;
    } else {
      cur_count_ = 1;
    }

    // 依旧count处理结果集
    if (cur_count_ > max_count_) {
      max_count_ = cur_count_;
      ret_.clear();
      ret_.push_back(root->val);
    } else if (cur_count_ == max_count_) {
      ret_.push_back(root->val);
    }

    pre_ = root;

    if (root->right) traversal(root->right);
  }

  vector<int> findMode(TreeNode* root) {
    traversal(root);
    return ret_;
  }

 private:
  TreeNode* pre_ = nullptr;
  int max_count_ = INT_MIN;
  int cur_count_ = 0;
  vector<int> ret_;
};

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

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 && !right) {
      return nullptr;
    } else if (!left && right) {
      return right;
    } else if (left && !right) {
      return left;
    } else {
      return root;
    }
  }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值