Leetcode刷题笔记Day9:二叉树Ⅳ

47 阅读3分钟

合并二叉树

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;
}

二叉树的最近公共祖先

  1. 求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从底向上的遍历方式。
  2. 在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。
  3. 要理解如果返回值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题解