二叉搜索树是一个有序树:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉搜索树
Leetcode: 530 二叉搜索树的最小绝对差
递归法
要掌握使用指针来记录之前的信息。
第一种解法:因为是二叉搜索树,因此中序遍历之后就会得到一个有序的数组,遍历这个数组计算就可以。
第二种方法:在递归的时候就可以直接计算得到结果了。
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;
}
};
迭代法
class Solution {
public:
int getMinimumDifference(TreeNode* root) {
stack<TreeNode*> st;
TreeNode* cur = root;
TreeNode* pre = NULL;
int result = INT_MAX;
while (cur != NULL || !st.empty()) {
if (cur != NULL) { // 指针来访问节点,访问到最底层
st.push(cur); // 将访问的节点放进栈
cur = cur->left; // 左
} else {
cur = st.top();
st.pop();
if (pre != NULL) { // 中
result = min(result, cur->val - pre->val);
}
pre = cur;
cur = cur->right; // 右
}
}
return result;
}
};
Leetcode: 501 二叉搜索树中的众数
递归法
第一种通用方法,遍历一遍树,把所有元素的频率放在对应的map上,输出最大的即可。代码为代码随想录提供:
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;
}
};
由于是二叉搜索树,因此有规律可循。因为中序搜索二叉搜索树有序,因此如果数值一样的话,那肯定都是在相邻节点上,因此相邻两个元素进行比较,输出频率最高的元素就可以。还需要定义一个结果集,放置所有最大频率的结果,这个结果集要随着最大频率的更新而更新。
class Solution {
private:
int maxcount = 0;
int count = 0;
TreeNode* pre = NULL;
vector<int> result;//定义全局函数
void searchnumber(TreeNode* node){
if(node == NULL) return;
searchnumber(node->left);
if(pre == NULL) count = 1;
else if(pre->val == node->val) count++;
else count =1;
pre = node;
if (count == maxcount) {
result.push_back(node->val);
}
if (count > maxcount) {
maxcount = count;
result.clear();
result.push_back(node->val);
}
searchnumber(node->right);
return;
}
public:
vector<int> findMode(TreeNode* root) {
maxcount = 0;
count = 0;
pre = NULL;
result.clear();
searchnumber(root);
return result;
}
};
也可以迭代法来实现,具体流程基本一样。
Leetcode: 236 二叉树的最近公共祖先
因为是从下到上,因此很明显,这道题需要使用后序遍历的操作。
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL || 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;
else if(left != NULL && right == NULL) return left;
else return NULL;
}
};