目录
一、(leetcode 530)二叉搜索树的最小绝对差
二、(leetcode 501)二叉搜索树中的众数
1.二叉搜索树
2.非二叉搜索树
思路
三、(leetcode 236)二叉树的最近公共祖先
一、(leetcode 530)二叉搜索树的最小绝对差
力扣题目链接
状态:已AC,get了用一个pre节点记录cur节点的前一个节点
二叉搜索树采用中序遍历,其实就是一个有序数组
class Solution {
private:
vector<int> vec;
void traversal(TreeNode* root) {if (root == NULL) return;traversal(root->left);vec.push_back(root->val); // 将二叉搜索树转换为有序数组traversal(root->right);
}
public:int getMinimumDifference(TreeNode* root) {vec.clear();traversal(root);if (vec.size() < 2) return 0;int result = INT_MAX;for (int i = 1; i < vec.size(); i++) { // 统计有序数组的最小差值result = min(result, vec[i] - vec[i-1]);}return result;}
};
二叉搜素树中序遍历过程中,也可直接计算,需要用一个pre节点记录一下cur节点的前一个节点
class Solution {
private:
int result = INT_MAX;
TreeNode* pre = NULL;
void traversal(TreeNode* cur) {if (cur == NULL) return;traversal(cur->left); // 左if (pre != NULL){ // 中result = min(result, cur->val - pre->val);}pre = cur; // 记录前一个traversal(cur->right); // 右
}
public:int getMinimumDifference(TreeNode* root) {traversal(root);return result;}
};
二、(leetcode 501)二叉搜索树中的众数
力扣题目链接
状态:非二叉搜索树的部分AC,二叉搜索树第一次涉及实时更新一个maxcount,需回顾
1.二叉搜索树
可以利用中序遍历方法来对重复元素进行检测,但是常规方法可能需要两次遍历,第一次统计出最大次数是多少,第二次找到出现这么多次数的元素。如果想一次遍历就可以得到结果,需要维护一个实时更新的最大值maxCount,并当它在更新时对答案数组进行清空操作(res.clear())
class Solution {
private:int maxCount = 0; // 最大频率int count = 0; // 统计频率TreeNode* pre = NULL;vector<int> 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<int> findMode(TreeNode* root) {count = 0;maxCount = 0;pre = NULL; // 记录前一个节点result.clear();searchBST(root);return result;}
};
2.非二叉搜索树
思路
把这个树都遍历,用map统计频率,把频率排个序,最后取前面高频的元素的集合
其中第二步的排序,在C++中如果使用std::map或者std::multimap可以对key排序,但不能对value排序。所以要把map转化数组即vector,再进行排序,vector里面放的是pair<int, int>
类型的数据,第一个int为元素,第二个int为出现频率。
class Solution {
private:void searchBST(TreeNode* cur, unordered_map<int, int>& map) { // 前序遍历if (cur == NULL) return ;map[cur->val]++; // 统计元素频率searchBST(cur->left, map);searchBST(cur->right, map);return ;
}
bool static cmp (const pair<int, int>& a, const pair<int, int>& b) {return a.second > b.second;
}
public:vector<int> findMode(TreeNode* root) {unordered_map<int, int> map; // key:元素,value:出现频率vector<int> result;if (root == NULL) return result;searchBST(root, map);vector<pair<int, int>> 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;}
};
三、(leetcode 236)二叉树的最近公共祖先
力扣题目链接
后序遍历(左右中)就是天然的回溯过程,可以根据左右子树的返回值,来处理中节点的逻辑
class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root == q || root == p || root == NULL) 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;else if (left != NULL && right == NULL) return left;else { // (left == NULL && right == NULL)return NULL;}}
};