《代码随想录》刷题打卡day15:二叉树part05

文章目录

【654.最大二叉树】

思路:和已知后序和中序遍历构造二叉树类似,一个一个找根节点然后分隔数组,注意每次分隔不用定义新的数组,而是通过下标索引直接在原数组上操作

c++ 复制代码
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        TreeNode* node = new TreeNode(0);
        if (nums.size() == 1) {
            node->val = nums[0];
            return node;
        }
        // 找到数组中最大的值和对应的下标
        int maxValue = 0;
        int maxValueIndex = 0;
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] > maxValue) {
                maxValue = nums[i];
                maxValueIndex = i;
            }
        }
        node->val = maxValue;
        // 最大值所在的下标左区间 构造左子树
        if (maxValueIndex > 0) {
            vector<int> newVec(nums.begin(), nums.begin() + maxValueIndex);
            node->left = constructMaximumBinaryTree(newVec);
        }
        // 最大值所在的下标右区间 构造右子树
        if (maxValueIndex < (nums.size() - 1)) {
            vector<int> newVec(nums.begin() + maxValueIndex + 1, nums.end());
            node->right = constructMaximumBinaryTree(newVec);
        }
        return node;
    }
【617.合并二叉树】

递归法:前序遍历,每次传入两个结点进行操作,容易理解。

c++ 复制代码
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if(root1 == nullptr) return root2;
        if(root2 == nullptr) return root1;
        TreeNode* node = new TreeNode(0);
        node->val = root1->val + root2->val;
        node->left = mergeTrees(root1->left, root2->left);
        node->right = mergeTrees(root1->right, root2->right);
        return node;
    }

迭代法:把两个树的节点同时加入队列进行比较,模拟层序遍历

c++ 复制代码
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.二叉搜索树中的搜索】

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

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

思路:都挺好想的,一下就懂。

递归法:

c++ 复制代码
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;
    }

迭代法:

c++ 复制代码
TreeNode* searchBST(TreeNode* root, int val) {
        while(root != nullptr){
            if(root->val > val){
                root = root->left;
            }else if(root->val < val){
                root = root->right;
            }else return root;
        }
        return root;
    }
【98.验证二叉搜索树】

思路:中序遍历下,输出的二叉搜索树节点的数值是有序序列。

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

递归法:

c++ 复制代码
vector<int> vec;
    void travelsal(TreeNode* root){
        if(root == nullptr) return;
        travelsal(root->left);
        vec.push_back(root->val);// 将二叉搜索树转换为有序数组
        travelsal(root->right);
    }
    bool isValidBST(TreeNode* root) {
        travelsal(root);
        for(int i = 1; i < vec.size(); i++){
            if(vec[i] <= vec[i-1]) return false;
        }
        return true;
    }

迭代法:模拟中序遍历,需要一个pre来记录前一个结点,还是有点绕,需要多思考熟悉。

c++ 复制代码
bool isValidBST(TreeNode* root) {
        stack<TreeNode*> st;
        TreeNode* cur = root;
        TreeNode* pre = nullptr;// 记录前一个结点
        while(!st.empty() || cur != nullptr){
            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;
    }

ps:我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点。

不能只判断左节点小于其根节点,右结点大于其根节点

反例:

相关推荐
zyl7658 小时前
FlashAttention 详解:从 GPU 硬件、普通 Attention 到分块计算与 Online Softmax
算法
爱读书的小胖12 小时前
LeetCode 122:买卖股票的最佳时机 II(C)解题分析
算法
结局无敌12 小时前
React Native for OpenHarmony 实战:三方库 react-native-modal-dialog 的鸿蒙化适配指南
深度学习·算法·react native·react.js·harmonyos
OPEN-F12 小时前
ROS2系列教程:上位机建图与导航(原理综合)
算法·机器人
weixin_3077791312 小时前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
AI wins12 小时前
c++新增頭文件
c++
Shadow(⊙o⊙)13 小时前
仿muduo实现高并发服务器——事件就绪管理Channel.hpp
服务器·c++
tomwang032213 小时前
路径优化建模、优化算法分类及工程化小结
算法·数学建模·分类
小羊没烦恼!13 小时前
Ajax与JSON的一些总结
android·java·前端·数据库·mysql·算法·okhttp
by2099913 小时前
哈希表——快速找到数据:冲突、删除与扩容的实现
数据结构·c++·哈希算法·散列表