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

LeetCode654

2025-02-13 18:52:43 星期四

题目描述:力扣654
文档讲解:代码随想录(programmercarl)654.最大二叉树
视频讲解:《代码随想录》算法视频公开课:又是构造二叉树,又有很多坑!| LeetCode:654.最大二叉树

代码随想录视频内容简记

构造一棵二叉树,用的是前序遍历。题目要求是

在最大值左边的子数组前缀上构建左子树,最大值右边的子数组后缀上构建右子树

所以要去不断寻找最大值index,然后左边的数组归左子树,右边的数组归右子树

梳理

  1. 确定函数construct的参数和返回值,在这道题目中直接用力扣的原函数即可。

  2. 确定递归的终止条件,if (nums.size() == 1) new TreeNode(0)表示此时的结点只有一个根节点了。

  3. 确定单层递归的逻辑,按照中——左——右序的顺序进行遍历.

    1. 首先是中。需要确定最大值对应的index,设置一个for循环,对index进行查找。 if (nums[i] > maxValue) maxValue = nums[i]; index = i;

    2. 之后是左if (index > 0)这个表示index左边的元素个数最少有1个,新建一个新的数组,newVec(nums.begin(), nums.begin() + index),之后进入递归,root->left = construct(newVec)

    3. 最后是右。同样,右边也是这样的顺序,if (index < nums.size() - 1),表示右边元素个数最少是1,新建数组,进入递归。

    最后返回根结点

LeetCode测试

点击查看代码
class Solution {
public:
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        TreeNode* node = new TreeNode(0);
        if (nums.size() == 1) {
            node->val = nums[0];
            return node;
        }
        int index;
        int maxValue = 0;
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] > maxValue) {
                maxValue = nums[i];
                index = i;
            }
        }
        node->val = maxValue;
        if (index > 0) {
            vector<int> newVec(nums.begin(), nums.begin() + index);
            node->left = constructMaximumBinaryTree(newVec);
        }
        if (index < (nums.size() - 1)) {
            vector<int> newVec(nums.begin() + index + 1, nums.end());
            node->right = constructMaximumBinaryTree(newVec);
        }
        return node;
    }
};

LeetCode617

题目描述:力扣617
文档讲解:代码随想录(programmercarl)617. 合并二叉树
视频讲解:《代码随想录》算法视频公开课:一起操作两个二叉树?有点懵!| LeetCode:617.合并二叉树

这道题用前、中、后序都可以,k哥说按照我们正常的遍历习惯来说,用前序即可。

梳理

  1. 首先定义一个函数TreeNode* merge(TreeNode* tree1, TreeNode* tree2)

  2. 确定递归的终止条件,if (tree1 == NULL) return tree2;if (tree2 == NULL) return tree1,这里的逻辑就是如果tree1遍历到空结点,那么直接返回tree2的结点即可(空不空都行)。注意,在遍历的过程中,tree1和tree2两课树是同时进行遍历的

  3. 确定单层递归的逻辑。可以新开辟一个结点。

    1. 中,root->val = tree1->val + tree2->val

    2. 左,root->left = merge(root->left, root->left);

    3. 右,root->right = merge(root->right, root->right);

    返回根结点

LeetCode测试

代码比较简单,写出来直接通过啦

点击查看代码
class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if (root1 == NULL) return root2;
        if (root2 == NULL) return root1;
        TreeNode* root = new TreeNode(0);
        root->val = root1->val + root2->val;
        root->left = mergeTrees(root1->left, root2->left);
        root->right = mergeTrees(root1->right, root2->right);
        return root;
    }
};

LeetCode700

题目描述:力扣700
文档讲解:代码随想录(programmercarl)700.二叉搜索树中的搜索
视频讲解:《代码随想录》算法视频公开课:不愧是搜索树,这次搜索有方向了!| LeetCode:700.二叉搜索树中的搜索

代码随想录视频内容简记

在二叉搜索树(BST)中,它本身自带顺序,就是根节点大于的他的左子树所有结点的值,但小于右子树所有结点的值

递归法

梳理

  1. 确定递归的终止条件,if (root == NULL || root->val == val) return root,直接返回一棵子树即可

  2. 确定单层递归的逻辑,if (root->val > val) result = search(root->left, val)这一步就是定义一个新的result结点,用来接住search的返回值。注意:只有这里的root->val > val时,表示的才是查询的val在root结点的左侧,就是注意符号。

迭代法

这道题的迭代法很简单,因为二叉搜索树自己已经有了顺序,只需要不断遍历即可。

LeetCode测试

递归法

点击查看代码
class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        if (root == NULL || root->val == val) return root;
        TreeNode* result = new TreeNode(0);
        if (root->val > val) result = searchBST(root->left, val);
        if (root->val < val) result = searchBST(root->right, val);
        return result;
    }
};

迭代法

点击查看代码
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 root;
    }
};

LeetCode98

题目描述:力扣98
文档讲解:代码随想录(programmercarl)98. 验证二叉搜索树
视频讲解:《代码随想录》算法视频公开课:你对二叉搜索树了解的还不够! | LeetCode:98.验证二叉搜索树

代码随想录视频内容简记

这道题有几种解法,首先是最初始的想法,通过中序遍历,将遍历结果存入一个数组中,之后验证这个数组是否是递增的,这是暴力法;第二种的想法就是不再额外使用数组,通过定义一个long long int的整型最小数,在中序遍历的过程中直接进行检查是否是递增顺序,但是这种方法也有局限性,k哥说在力扣中有int的整型最小数,这种比较是通过root->val > maxValue,则进行赋值,一旦在给出的测试用例中root->val有更小的值,那么maxValue就无法完成更新了;所以最后的通过使用双指针的思想来完成的

梳理

  1. 确定递归的终止条件if (root == NULL) return true;这种就是所有二叉树的类型他都符合

  2. 确定单层递归的逻辑。

    1. 首先是左,bool left = isValidBST(root->left)

    2. 然后是中,首先定义一个新的TreeNode* pre = NULL,首先让他为空,之后if (pre != NULL && root->val <= pre->val) return false,一旦出现false那么就不是一棵平衡二叉树了。注意在这之后要pre = root;这么做是为了让pre不会进入第一次遍历的if判断中,并能在第二次判断时进入正常。

    3. 最后是右,bool right = isValidBST(root->right)

    最后返回 return left && right,只有当左右子树都同时为true才能返回

LeetCode测试

注意,这里的TreeNode* pre = NULL也要定义在递归的外部,也就是bool函数的外部。

点击查看代码
class Solution {
public:
    TreeNode* pre = NULL;
    bool isValidBST(TreeNode* root) {
        if (root == NULL) return true;
        // 左
        bool left = isValidBST(root->left);
        // 中
        if (pre != NULL && root->val <= pre->val) return false;
        pre = root;
        // 右
        bool right = isValidBST(root->right);
        return left && right;
    }
};
posted on   bnbncch  阅读(1278)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示