参考
题目一:LeetCode 530.二叉搜索树的最小绝对差
这个题和之前的验证二叉搜索树的题一样,可以将二叉树转化为数组,然后遍历数组求差值就可以了。
class Solution {
public:
void traversal(vector<int>& nums,TreeNode* root)
{
if(root == nullptr) return ;
traversal(nums,root->left);
nums.push_back(root->val);
traversal(nums,root->right);
}
int getMinimumDifference(TreeNode* root) {
vector<int> nums;
traversal(nums,root);
int min = nums[1]-nums[0];
for(int i=1;i<nums.size()-1;i++)
min = (min > nums[i+1] - nums[i]) ? nums[i+1] - nums[i] : min;
return min;
}
}
如果不使用数组,可以额外定义一个指针记录上一个节点,在遍历二叉树过程中就可以计算差值,代码如下:
class Solution {
public:
int min = INT_MAX;
TreeNode* pre = nullptr;
void traversal(TreeNode* root)
{
if(root == nullptr) return;
traversal(root->left);
if(pre != nullptr)
min = (root->val - pre->val < min) ? (root->val - pre->val) : min;
pre = root;
traversal(root->right);
}
int getMinimumDifference(TreeNode* root) {
traversal(root);
return min;
}
};
题目二:LeetCode 501.二叉搜索树中的众数
用unordered_map来统计每个数值出现的次数,然后将unordered_map放入的vector中,用sort()函数进行排序,再输出结果。这样做比较简单,但没有用到二叉搜索树的性质。
class Solution {
public:
void traversal(TreeNode* root,unordered_map<int,int>& mp)
{
if(root == nullptr) return ;
traversal(root->left,mp);
mp[root->val]++;
traversal(root->right,mp);
}
bool static comp(pair<int,int>& x,pair<int,int>& y)
{
return x.second > y.second;
}
vector<int> findMode(TreeNode* root) {
unordered_map<int,int> mp;
vector<int> res;
traversal(root,mp);
vector<pair<int,int>> vec(mp.begin(),mp.end());
sort(vec.begin(),vec.end(),comp);
res.push_back(vec[0].first);
for(int i=1;i<vec.size();i++)
if(vec[i].second == vec[0].second) res.push_back(vec[i].first);
else break;
return res;
}
};
题目三:LeetCode 236. 二叉树的最近公共祖先
- 确定递归函数的参数和返回值
参数:根节点,节点q和节点q
返回值:如果遇到p或者q,就把q或者p返回,返回值不为空,就说明找到了q或者p
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
- 确定终止条件
如果传入的根节点为空,说明已经到底了,返回空;如果根节点等于p或q,就返回p或者q。
if (root == q || root == p || root == NULL) return root;
- 确定单层递归逻辑
在递归函数有返回值的情况下:如果要搜索一条边,递归函数返回值不为空的时候,立刻返回,如果搜索整个树,直接用一个变量left、right接住返回值,这个left、right后序还有逻辑处理的需要,也就是后序遍历中处理中间节点的逻辑(也是回溯)。
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
如果left 和 right都不为空,说明此时root就是最近公共节点。这个比较好理解
如果left为空,right不为空,就返回right,说明目标节点是通过right返回的,反之亦然。
if (left == NULL && right != NULL) return right;
else if (left != NULL && right == NULL) return left;
else { // (left == NULL && right == NULL)
return NULL;
}
整体代码如下:
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;
}
}
};