Day20 二叉树 654 617 700 98

68 阅读3分钟

654. 最大二叉树

心得

  • 类似之前前序中序的构造方法,左闭右开区间的if条件判断上出错
  • 对于终止条件和if的关系需要一一对应

题解

  • 构造二叉树一定用前序遍历,注意数组index的优化
  • 本题left和right不等会报错,结合题意求最值的时候,哨兵好用
  • 最好还是采用数组和index的方式,该情况下最后终止条件为空节点;对于新建vector则终止条件叶子结点,同时结合递归空节点不如递归即可
class Solution {
public:
    TreeNode* traversal(vector<int>& nums, int left, int right) {
        if (left >= right) return nullptr;
        int MaxIndex = left;
        for (int i = left + 1; i < right; i++) {
            if (nums[i] > nums[MaxIndex]) {
                MaxIndex = i;
            }
        }
        TreeNode* root = new TreeNode(nums[MaxIndex]);
        root->left = traversal(nums, left, MaxIndex);
        root->right = traversal(nums, MaxIndex + 1, right);
        return root;

    }
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        return traversal(nums, 0, nums.size());
    }
};

617. 合并二叉树

心得

  • 中序即可

题解

  • 可以复用参数不用创建新node,其实前中后序都可以
  • 迭代法可以用层序,队列,保存然后比较即可
class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if (root1 == nullptr) return root2;
        if (root2 == nullptr) return root1;
        root1->val = root1->val + root2->val;
        root1->left =  mergeTrees(root1->left, root2->left);
        root1->right = mergeTrees(root1->right, root2->right);
        return root1; 
    }
};

// 层序
class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        if (t1 == NULL) return t2;
        if (t2 == NULL) return t1;
        queue<TreeNode*> que;
        que.push(t1);
        que.push(t2);
        while(!que.empty()) {
            TreeNode* node1 = que.front(); que.pop();
            TreeNode* node2 = que.front(); que.pop();
            // 此时两个节点一定不为空,val相加
            node1->val += node2->val;

            // 如果两棵树左节点都不为空,加入队列
            if (node1->left != NULL && node2->left != NULL) {
                que.push(node1->left);
                que.push(node2->left);
            }
            // 如果两棵树右节点都不为空,加入队列
            if (node1->right != NULL && node2->right != NULL) {
                que.push(node1->right);
                que.push(node2->right);
            }

            // 当t1的左节点 为空 t2左节点不为空,就赋值过去
            if (node1->left == NULL && node2->left != NULL) {
                node1->left = node2->left;
            }
            // 当t1的右节点 为空 t2右节点不为空,就赋值过去
            if (node1->right == NULL && node2->right != NULL) {
                node1->right = node2->right;
            }
        }
        return t1;
    }
};

700. 二叉搜索树中的搜索

心得

  • 重在了解二叉搜索树BST性质

题解

  • 递归,也利用其特性
  • 掌握迭代,二叉搜索树具有有序性,对于查找元素来说不需要回溯,不需要借助栈或者队列
class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        if (root == nullptr || root->val == val ) return root;
        return root->val > val ? searchBST(root->left, val) : searchBST(root->right, val);
    }
};

// 迭代
class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        while (root != NULL) {
            if (root->val > val) root = root->left;
            else if (root->val < val) root = root->right;
            else return root;
        }
        return NULL;
    }
};

98. 验证二叉搜索树

心得

  • 中序遍历得递增数组然后判断即可
  • 注意判断条件根节点大于左,小于右存在误区,可能左下面有更大的,所以要么全局保存最值,要么与前一个比较

题解

  • 数组保存需要额外空间,只要把数组的比较逻辑拿到树中即可,用类似双指针的临时变量来判断是否递增,对于&&前的非空判断很多情况下都是后一个的执行满足要求的必要判断
  • 二叉搜索一定是中序遍历
class Solution {
public:
    TreeNode* prev = nullptr;
    bool isValidBST(TreeNode* root) {
        if (root == nullptr) return true;
        bool left = isValidBST(root->left);
        if (prev != nullptr && prev->val >= root->val) return false;
        prev = root;
        bool right = isValidBST(root->right);
        return left && right;
    }
};