题目:530. 二叉搜索树的最小绝对差 - 力扣(LeetCode)
思路:
1.中序遍历二叉树得到一个有序数组,然后在有序数组里求最小差值。
代码:
class Solution {
public:
vector<int> vec;
void traversal(TreeNode* root){//中序遍历得到有序数组
if(root == NULL) return;
traversal(root->left);
vec.push_back(root->val);
traversal(root->right);
}
int getMinimumDifference(TreeNode* root) {
vec.clear();
traversal(root);
int MinValue = vec[1] - vec[0];//MinValue记录最小差值,初始化前两个元素的差值
for(int i = 1; i < vec.size(); i++){
if(vec[i] - vec[i - 1] <= MinValue){
MinValue = vec[i] - vec[i - 1];//遍历数组时,更新最小差值
}
}
return MinValue;
}
};
双指针:定义一个pre指针指向前一个节点,cur指针指向当前节点,在中序遍历的时候直接得到前后两个元素的差值。
代码:
class Solution {
public:
TreeNode* pre = NULL;
int result = INT_MAX;//定义全局变量记录最小差值
void traversal(TreeNode* cur){
if(cur == NULL) return;
traversal(cur->left);//左
if(pre != NULL){//中
//中序遍历时不断更新result
result = cur->val - pre->val < result ? cur->val - pre->val : result;
}
pre = cur;
traversal(cur->right);//右
}
int getMinimumDifference(TreeNode* root) {
traversal(root);
return result;
}
};
题目:501. 二叉搜索树中的众数 - 力扣(LeetCode)
思路:
1.先中序遍历二叉树,用map统计元素出现的频率。
2.将map放进vecor数组中,并以频率由高到低进行排序。
3.统计数组中频率出现最高的元素。
代码:
class Solution {
public:
unordered_map<int, int> map;
void traversal(TreeNode* root){
if(root == NULL) return;
traversal(root->left);
map[root->val]++;
traversal(root->right);
return;
}
bool static cmp(const pair<int, int>& a, const pair<int, int>& b){
return a.second > b.second;//vec数组按照频率递减进行排序
}
vector<int> findMode(TreeNode* root) {
traversal(root);
vector<int> result;
if(root == NULL) return result;
vector<pair<int, int>> vec(map.begin(), map.end());
sort(vec.begin(), vec.end(), cmp);
result.push_back(vec[0].first);//先将vec数组首元素即频率最高的元素放进result数组中
for(int i = 1; i < vec.size(); i++){
if(vec[i].second == vec[i - 1].second){//然后从下标i=1开始遍历,如果找到频率和首元素频率相等的元素,就加入result数组中
result.push_back(vec[i].first);
}else{//一旦不相等,说明不是频率最高的元素,退出for循环
break;
}
}
return result;
}
};
双指针实现:
class Solution {
int count = 0;
int MaxCount = 0;
vector<int> result;
TreeNode* pre = NULL;
void traversal(TreeNode* cur){
if(cur == NULL) return;
traversal(cur->left);
if(pre == NULL){
count = 1;
}else if(pre->val == cur->val){
count++;
}else{
count = 1;
}
pre = cur;
if(count == MaxCount) result.push_back(cur->val);
if(count > MaxCount){
MaxCount = count;
result.clear();
result.push_back(cur->val);
}
traversal(cur->right);
return;
}
public:
vector<int> findMode(TreeNode* root) {
traversal(root);
return result;
}
};
题目:236. 二叉树的最近公共祖先 - 力扣(LeetCode)
思路:
1.递归函数返回值以及参数:需要递归函数返回值,来告诉我们是否找到节点q或者p,那么返回值为bool类型就可以了。
2.终止条件:遇到空的话,因为树都是空了,所以返回空。如果 root == q,或者 root == p,说明找到 q p ,则将其返回。
3.单层递归逻辑:在递归函数有返回值的情况下:如果要搜索一条边,递归函数返回值不为空的时候,立刻返回,如果搜索整个树,直接用一个变量left、right接住返回值,这个left、right后序还有逻辑处理的需要,也就是后序遍历中处理中间节点的逻辑(也是回溯)。
具体见:代码随想录 (programmercarl.com)
代码:
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;
}
}
};