合并二叉树
- 力扣题目链接
- 这道题目怎么遍历都可以!以前序遍历为例:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
// 前序遍历
if(!root1) return root2;
if(!root2) return root1;
root1->val+=root2->val;
root1->left=mergeTrees(root1->left, root2->left);
root1->right=mergeTrees(root1->right, root2->right);
return root1; //千万别忘了
}
二叉搜索树中的搜索
- 力扣题目地址
- 真的好久没做过如此简单的题目了
TreeNode* searchBST(TreeNode* root, int val) {
while(root!=nullptr){
if(val<root->val) root=root->left;
else if(val>root->val) root=root->right;
else return root;
}
return nullptr;
}
验证二叉搜索树
-
题目要点在于中序遍历是有序数组!
-
那么我们在验证二叉搜索树的时候,有两个陷阱:
- 陷阱一
不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了,而是左子树都小于中间节点,右子树都大于中间节点。
- 陷阱二
在一个有序序列求最值的时候,不要定义一个全局遍历,然后遍历序列更新全局变量求最值。因为最值可能就是 int 或者 long的最小值。
推荐要通过前一个数值(pre)和后一个数值比较(cur),得出最值。
long maxVal=LONG_MIN; // 因为后台测试数据中有int最小值
bool isValidBST(TreeNode* root) {
if(root==nullptr) return true;
bool left=isValidBST(root->left); // 左
// 中序遍历
if(maxVal<root->val) maxVal=root->val;
else return false;
// 注意这里的不对称性
bool right=isValidBST(root->right); // 右
return left && right;
}
二叉搜索树的最小绝对差
- 力扣题目链接
- 只需在上题基础上稍作修改!
int result=INT_MAX;
TreeNode* pre=nullptr;
void traversal(TreeNode* root){
if(root==nullptr) return;
traversal(root->left);
if(pre!=nullptr) result=min(result, root->val-pre->val);
pre=root;
traversal(root->right);
}
int getMinimumDifference(TreeNode* root) {
traversal(root);
return result;
}
二叉搜索树中的众数
int maxCount=0, count=0;
vector<int> result;
TreeNode* pre=nullptr;
void searchBST(TreeNode* root){
if(root==nullptr) return;
searchBST(root->left);
if(pre==nullptr) count=1;
else if(pre->val==root->val) count++;
else count=1;
pre=root;
if(count==maxCount) result.push_back(root->val);
else if(count>maxCount){
result.clear();
result.push_back(root->val);
maxCount=count;
}
searchBST(root->right);
return;
}
vector<int> findMode(TreeNode* root) {
searchBST(root);
return result;
}
二叉树的最近公共祖先
- 力扣题目链接
- 回溯过程小结:
- 求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从底向上的遍历方式。
- 在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。
- 要理解如果返回值left为空,right不为空为什么要返回right,为什么可以用返回right传给上一层结果。
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);
// 情况1:left和right都不空,root是最近公共祖先
if(left && right) return root;
// 情况2:left空,right不空,返回right,其他情况同理
if(!left && right) return right;
if(left && !right) return left;
else return nullptr;
}
参考资料
[1] 代码随想录
[2] Leetcode题解