代码随想录算法训练营第20天| Leetcode 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

目录

Leetcode 654.最大二叉树

Leetcode 617.合并二叉树

Leetcode 700.二叉搜索树中的搜索

Leetcode 98.验证二叉搜索树


Leetcode 654.最大二叉树

题目链接:Leetcode 654.最大二叉树

题目描述:给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

  • 二叉树的根是数组中的最大元素。
  • 左子树是通过数组中最大值左边部分构造出的最大二叉树。
  • 右子树是通过数组中最大值右边部分构造出的最大二叉树。

通过给定的数组构建最大二叉树,并且输出这个树的根节点。

思路:构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。首先遍历数组找到最大值作为根节点的val,然后将数组切割成左右两个(我这里采用左闭右开区间),递归执行上述操作。递归的终止条件是当数组的左边界大于等于右边界的时候。

代码如下:

class Solution {
public:
    TreeNode* traversal(vector<int>& nums, int left, int right) { //左开右闭区间
        if (left >= right)
            return nullptr;
        //分割点下标:max
        int max = left;
        for (int i = left + 1; i < right; i++) {
            if (nums[i] > nums[max])
                max = i;
        }
        TreeNode* root = new TreeNode(nums[max]);
        //递归左右区间
        root->left = traversal(nums, left, max);
        root->right = traversal(nums, max + 1, right);
        //返回根节点
        return root;
    }
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        return traversal(nums, 0, nums.size());
    }
};

Leetcode 617.合并二叉树

题目链接:Leetcode 617.合并二叉树

题目描述:给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

思路:本题乍一看需要操作两个二叉树,容易被吓到,实则不然。由于新二叉树为两个二叉树相同位置的数值val相加,因此只需要以一个树为基础,同时遍历两个树的相同位置节点,只要某个位置节点不为空就加上对应数值val。递归法非常简洁,迭代法由于需要创建两个队列,比较麻烦。

代码如下:(递归法)

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if (root1 == nullptr)
            return root2;
        if (root2 == nullptr)
            return root1;
        //合并操作
        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;
    }
};

Leetcode 700.二叉搜索树中的搜索

题目链接:Leetcode 700.二叉搜索树中的搜索

题目描述:给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。

思路:不会吧?根据二叉搜索树来搜索?(猜猜它为什么叫二叉搜索树?)不过这道题算是帮我复习一下二叉搜索树的基本内容。二叉搜索树,也叫二叉排序树,二叉查找树。这种结构具有如下性质:

二叉搜索树是一个有序树:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉搜索树

对于二叉搜索树的查找我的理解是逻辑上类似于二分查找,每次比较待查找的值target和中间节点的值val,如果val>target,就向左子树中查找;如果val<target,就去右子树中查找,相等则返回。

代码如下:(递归法)

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        if (root == nullptr || root->val == val)
            return root;
        if (root->val > val)
            return searchBST(root->left, val);
        if (root->val < val)
            return searchBST(root->right, val);
        return nullptr;
    }
};

(迭代法)

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

Leetcode 98.验证二叉搜索树

题目链接:Leetcode 98.验证二叉搜索树

题目描述:给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

  • 节点的左子树只包含小于当前节点的数。
  • 节点的右子树只包含大于当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

思路:这道题同样可以利用二叉搜索树的性质来做。由于二叉搜索树左节点的节点的值<中间节点的值<右节点的值因此可以将二叉树的中序遍历存入数组中,判断该数组内元素是否是有序的就可以了。注意:二叉搜索树中不存在相同元素

代码如下:(递归法)

class Solution {
public:
    vector<int> vec;
    void traversal(TreeNode* root) {
        if (root == nullptr)
            return;
        traversal(root->left);
        vec.push_back(root->val);
        traversal(root->right);
    }
    bool isValidBST(TreeNode* root) {
        traversal(root);
        for (int i = 1; i < vec.size(); i++) {
            if (vec[i] <= vec[i - 1]) //二叉搜索树不能有重复元素,因此要带等号
                return false;
        }
        return true;
    }
};

(迭代法)

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        stack<TreeNode*> st;
        TreeNode* cur = root;
        TreeNode* pre = nullptr; //记录前一个节点
        while (cur != nullptr || !st.empty()) {
            if (cur != nullptr) {
                st.push(cur);
                cur = cur->left; //左
            } else {
                cur = st.top(); //中
                st.pop();
                if (pre != nullptr && cur->val <= pre->val)
                    return false;
                pre = cur;
                cur = cur->right; //右
            }
        }
        return true;
    }
};

总结:今天的题比较基础,完成的比较轻松,可以用来复习二叉树的基础内容。

最后,如果文章有错误,请在评论区或私信指出,让我们共同进步!

  • 23
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值