算法训练day20Leetcode654最大二叉树617合并二叉树700二叉树中的1搜索98验证二叉搜索树

这篇具有很好参考价值的文章主要介绍了算法训练day20Leetcode654最大二叉树617合并二叉树700二叉树中的1搜索98验证二叉搜索树。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

654 最大二叉树

题目

https://leetcode.cn/problems/maximum-binary-tree/description/

我的想法

中序遍历递归,找到最大值然后作为根节点

题目分析

凡是构造二叉树的题目都用前序遍历 (中左右)

为先构造中间节点,然后递归构造左子树和右子树。

确定递归函数的参数和返回值
参数传入的是存放元素的数组,返回该数组构造的二叉树的头结点,返回类型是指向节点的指针。

1.确定终止条件

题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。

那么应该定义一个新的节点,并把这个数组的数值赋给新的节点,然后返回这个节点。 这表示一个数组大小是1的时候,构造了一个新的节点,并返回。

TreeNode* node = new TreeNode(0);
if (nums.size() == 1) {
    node->val = nums[0];
    return node;
}

确定单层递归逻辑

这里有三步工作

先要找到数组中最大的值和对应的下标, 最大的值构造根节点,下标用来下一步分割数组。

最大值所在的下标左区间 构造左子树
这里要判断maxValueIndex > 0,因为要保证左区间至少有一个数值。

最大值所在的下标右区间 构造右子树
判断maxValueIndex < (nums.size() - 1),确保右区间至少有一个数值。

acm模式代码

#include <iostream>
#include <vector>
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x):val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode* left, TreeNode* right):val(x), left(left), right(right) {}

};

class Solution {
public:
    TreeNode* constrcuctMaxinumBinaryTree(std::vector<int>& num) {
        TreeNode* node = new TreeNode(0);
        if (num.size() == 1) {
            node->val = num[0];
            return node;
        }
        int maxvalue = 0;
        int maxvalueIndex = 0;
        for (int i = 0; i < num.size(); i++) {
            if (num[i] > maxvalue) {
                maxvalue = num[i];
                maxvalueIndex = i;
            }
        }
        node->val = maxvalue;
        if(maxvalueIndex > 0) {
            std::vector<int> newVec(num.begin(), num.begin() + maxvalueIndex);
            node->left = constrcuctMaxinumBinaryTree(newVec);
        }
        if (maxvalueIndex < num.size()-1) {
            std::vector<int> newVec(num.begin() + maxvalueIndex + 1, num.end());
            node->right = constrcuctMaxinumBinaryTree(newVec);
        }
        return node;
    }
};

void printTree(TreeNode* node) {
    if (node != nullptr) {
        printTree(node->left);
        std::cout << node->val << " ";
        printTree(node->right);
    }
}

int main() {
    // 创建一个整数向量
    std::vector<int> nums = {3, 2, 1, 6, 0, 5};

    // 创建Solution实例并构建最大二叉树
    Solution solution;
    TreeNode* root = solution.constrcuctMaxinumBinaryTree(nums);

    // 打印构建的二叉树
    std::cout << "The constructed maximum binary tree (inorder): ";
    printTree(root);
    std::cout << std::endl;

    // 注意:这里没有删除TreeNode的实例,实际应用中应考虑内存管理

    return 0;
}

617 合并二叉树

题目描述

https://leetcode.cn/problems/merge-two-binary-trees/description/

我的想法

还是构造新的二叉树,选择前序遍历

题目分析

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

我们来按照递归三部曲来解决:

  1. 确定递归函数的参数和返回值:
    首先要合入两个二叉树,那么参数至少是要传入两个二叉树的根节点,返回值就是合并之后二叉树的根节点。

代码如下:

TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {

  1. 确定终止条件:
    因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL)。

反过来如果t2 == NULL,那么两个数合并就是t1(如果t1也为NULL也无所谓,合并之后就是NULL)。

代码如下:

if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2
if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1
  1. 确定单层递归的逻辑
    单层递归的逻辑就比较好写了,这里我们重复利用一下t1这个树,t1就是合并之后树的根节点(就是修改了原来树的结构)。

那么单层递归中,就要把两棵树的元素加到一起。

t1->val += t2->val;

接下来t1 的左子树是:合并 t1左子树 t2左子树之后的左子树。

t1 的右子树:是 合并 t1右子树 t2右子树之后的右子树。

最终t1就是合并之后的根节点。

代码如下:

t1->left = mergeTrees(t1->left, t2->left);
t1->right = mergeTrees(t1->right, t2->right);
return t1;

acm完整代码

#include <iostream>

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x):val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode* left, TreeNode* right):val(x), left(left), right(right) {}
};

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

void printTree(TreeNode* node) {
    if (node != nullptr) {
        std::cout << node->val << " ";

        printTree(node->left);
        printTree(node->right);
    }
}

int main() {
    // 创建两个树的根节点
    TreeNode* root1 = new TreeNode(1);
    root1->left = new TreeNode(3);
    root1->right = new TreeNode(2);
    root1->left->left = new TreeNode(5);

    TreeNode* root2 = new TreeNode(2);
    root2->left = new TreeNode(1);
    root2->right = new TreeNode(3);
    root2->left->right = new TreeNode(4);
    root2->right->right = new TreeNode(7);

    // 合并两棵树
    Solution solution;
    TreeNode* mergedTree = solution.mergeTrees(root1, root2);

    // 打印合并后的树
    std::cout << "The merged tree (inorder): ";
    printTree(mergedTree);
    std::cout << std::endl;

    // 注意:这里没有删除TreeNode的实例,实际应用中应考虑内存管理
    delete root1;
    delete root2;
    delete mergedTree;
    return 0;
}

700二叉搜索树中的搜索

题目描述

https://leetcode.cn/problems/search-in-a-binary-search-tree/description/

我的想法

直接用前序遍历,遍历到值相等的节点就作为根节点返回

题目分析

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

若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉搜索树
这就决定了,二叉搜索树,递归遍历和迭代遍历和普通二叉树都不一样。

本题,其实就是在二叉搜索树中搜索一个节点。那么我们来看看应该如何遍历。

递归法

  1. 确定递归函数的参数和返回值
    递归函数的参数传入的就是根节点和要搜索的数值,返回的就是以这个搜索数值所在的节点。

代码如下:

TreeNode* searchBST(TreeNode* root, int val)

  1. 确定终止条件
    如果root为空,或者找到这个数值了,就返回root节点。
if (root == NULL || root->val == val) return root;

  1. 确定单层递归的逻辑
    看看二叉搜索树的单层递归逻辑有何不同。

因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。

如果root->val > val,搜索左子树,如果root->val < val,就搜索右子树,最后如果都没有搜索到,就返回NULL。

代码如下:

TreeNode* result = NULL;
if (root->val > val) result = searchBST(root->left, val);
if (root->val < val) result = searchBST(root->right, val);
return result;

acm模式代码

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

        TreeNode* leftSearch = searchBST(root->left, val);
        if (leftSearch != nullptr) return leftSearch;

        return searchBST(root->right, val);
    }

    void printTree(TreeNode* root) {
        if (root == nullptr) return;
        std::cout << root->val << " ";
        printTree(root->left);
        printTree(root->right);
    }
};

int main() {
    TreeNode* node = new TreeNode(3);
    node->left = new TreeNode(2);
    node->right = new TreeNode(3);
    node->left->left = new TreeNode(4);
    node->left->right = new TreeNode(5);

    Solution* sol = new Solution();
    TreeNode* newnode = sol->searchBST(node, 2);
    sol->printTree(newnode);

    // 注意:这里没有删除TreeNode的实例和Solution的实例,实际应用中应考虑内存管理

    return 0;
}

98验证二叉搜索树

题目描述

https://leetcode.cn/problems/validate-binary-search-tree/description/

我的想法

采用后序遍历,比较两个儿子是否满足条件。

题目分析

二叉搜索类题目中序遍历是有序的

有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。

可以递归中序遍历将二叉搜索树转变成一个数组,代码如下:

vector<int> vec;
void traversal(TreeNode* root) {
    if (root == NULL) return;
    traversal(root->left);
    vec.push_back(root->val); // 将二叉搜索树转换为有序数组
    traversal(root->right);
}
然后只要比较一下,这个数组是否是有序的,注意二叉搜索树中不能有重复元素。

traversal(root);
for (int i = 1; i < vec.size(); i++) {
    // 注意要小于等于,搜索树里不能有相同元素
    if (vec[i] <= vec[i - 1]) return false;
}
return true;

完整acm模式代码

#include <iostream>
#include <vector>

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x):val(x) ,left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode* left, TreeNode* right) {}
};

class Solution{
public:
    std::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;
    }
};

int main() {
    // Create nodes
    TreeNode* n1 = new TreeNode(2);
    TreeNode* n2 = new TreeNode(1);
    TreeNode* n3 = new TreeNode(3);

    // Construct the tree
    n1->left = n2;
    n1->right = n3;

    // Create a solution instance
    Solution solution;

    // Check if the tree is a valid BST
    bool result = solution.isValidBST(n1);
    if (result) {
        std::cout << "The tree is a valid BST." << std::endl;
    } else {
        std::cout << "The tree is not a valid BST." << std::endl;
    }

    // Clean up
    delete n1;
    delete n2;
    delete n3;

    return 0;
}

今日学习链接

https://www.bilibili.com/video/BV1wG411g7sF
https://programmercarl.com/0098.%E9%AA%8C%E8%AF%81%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html文章来源地址https://www.toymoban.com/news/detail-812504.html

到了这里,关于算法训练day20Leetcode654最大二叉树617合并二叉树700二叉树中的1搜索98验证二叉搜索树的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法训练day15Leetcode102二叉树层序遍历226翻转二叉树101对称二叉树

    https://www.bilibili.com/video/BV1ue4y1Y7Mf/?vd_source=8272bd48fee17396a4a1746c256ab0ae 层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。 需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先

    2024年01月18日
    浏览(35)
  • 算法训练day17leetcode110平衡二叉树257二叉树的所有路径404左叶子之和

    https://www.bilibili.com/video/BV1GY4y1K7z8/?vd_source=8272bd48fee17396a4a1746c256ab0ae https://programmercarl.com/0404.%E5%B7%A6%E5%8F%B6%E5%AD%90%E4%B9%8B%E5%92%8C.html#%E6%80%9D%E8%B7%AF 采用后序递归遍历,比较左右子树的高度,相差小于等于1 前序,中左右,从根节点到叶子节点,会一直向下遍历下去,不会返回信

    2024年01月19日
    浏览(25)
  • 算法训练day13Leetcode144 145 94 二叉树的前(中)(后)序遍历

    https://www.bilibili.com/video/BV1Hy4y1t7ij/?vd_source=8272bd48fee17396a4a1746c256ab0ae 二叉树的种类 在我们解题过程中二叉树有两种主要的形式:满二叉树和完全二叉树。 满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。 什么

    2024年01月15日
    浏览(44)
  • 654. 最大二叉树

    思路: https://leetcode.cn/problems/maximum-binary-tree/solution/zui-da-er-cha-shu-by-leetcode-solution-lbeo/

    2024年02月11日
    浏览(63)
  • 每日一练:LeeCode-654、最大二叉树【二叉树+DFS+分治】

    本文是力扣LeeCode-654、最大二叉树【二叉树+DFS+分治】 学习与理解过程,本文仅做学习之用,对本题感兴趣的小伙伴可以出门左拐LeeCode。 给定一个 不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建 一个根节点 , 其值为 nums 中的最大值 。 递归

    2024年02月21日
    浏览(32)
  • C++力扣题目654--最大二叉树

    给定一个不重复的整数数组  nums  。  最大二叉树  可以用下面的算法从  nums  递归地构建: 创建一个根节点,其值为  nums  中的最大值。 递归地在最大值  左边  的  子数组前缀上  构建左子树。 递归地在最大值  右边  的  子数组后缀上  构建右子树。 返回  nums  构

    2024年01月20日
    浏览(31)
  • 算法训练day18Leetcode找树左下角的值112路径总和106从中序和后续遍历构造二叉树

    找出深度最大的叶子节点,左遍历在前 我们来分析一下题目:在树的最后一行找到最左边的值。 首先要是最后一行,然后是最左边的值。 如果使用递归法,如何判断是最后一行呢,其实就是深度最大的叶子节点一定是最后一行。 如果对二叉树深度和高度还有点疑惑的话,请

    2024年01月21日
    浏览(36)
  • 【LeetCode】617.合并二叉树

    给你两棵二叉树:  root1  和  root2  。 想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则

    2024年02月13日
    浏览(54)
  • day20 最大的二叉树 合并二叉树 二叉搜索树中的搜索 验证二叉搜索树

    题目链接:654 最大二叉树 题意 根据不重复的整数数组nums构建最大的二叉树 ,根节点是数组中的最大值,最大值左边的子数组构建左子树,最大值右边的子数组构建右子树 nums数组中最少含有1个元素,并且nums中的元素数值均大于等于0 递归  递归三部曲: 1)确定递归函数的

    2024年01月21日
    浏览(28)
  • LeetCode刷题——617. 合并二叉树

    给你两棵二叉树: root1 和 root2 。 想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为

    2024年02月13日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包