《录鼎记》——第N章,做一大半心有点乱,不想起标题了

今日内容

  • 654.最大二叉树
  • 617.合并二叉树
  • 700.二叉搜索树中的搜索
  • 98.验证二叉搜索树

一、构造最大二叉树

力扣题目地址 (opens new window)

由于本题是找到最大节点的值作为根节点,然后左侧数组构造左子树,右侧数组构造右子树。

其中肯定是有一个递归的过程,所以就涉及到递归三部曲:

1、确定顶柜函数的参数和返回值

构造二叉树,所以返回的是头节点,然后参数使我们依据的存放元素的数组

Treenode* constructTree(vector<int>& nums)

2、终止条件

题中说输入的数组大小一定大于等于1,故不考虑数组为空的情况,那如果遍历中数组大小等于1,说明此时已经是最后一个节点也就是叶子节点。

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

3、单层递归逻辑

先找到最大值,用最大值构造根节点,下标用于分割数组

然后再下标的左区间构造左子树,右区间构造右子树

int maxValue = 0;
int maxValueIndex = 0;
for (int i = 0; i < nums.size(); i++) {
    if (nums[i] > maxValue) {
        maxValue = nums[i];
        maxValueIndex = i;
    }
}
TreeNode* node = new TreeNode(0);
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);
}

下面是整体代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     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* constructMaximumBinaryTree(vector<int>& nums) {
        TreeNode* node =new TreeNode(0);
        if(nums.size()==1){
            node->val=nums[0];
            return node;
        }

        int maxvalue=0;
        int maxvindex=0;
        for(int i=0;i<nums.size();i++){
            if(nums[i]>maxvalue){
                maxvalue=nums[i];
                maxvindex=i;
            }
        }

        node->val=maxvalue;
        if(maxvindex>0){
            vector<int> newVec(nums.begin(),nums.begin()+ maxvindex);
            node->left =constructMaximumBinaryTree(newVec);
        }

        if(maxvindex<(nums.size()-1)){
            vector<int> newVec(nums.begin()+maxvindex+1,nums.end());
            node->right =constructMaximumBinaryTree(newVec);

        }
        return node;

    }
};

今天有脑子有耐心分析代码,明显比上次好多了,逻辑清晰一点。

二、合并二叉树

力扣题目链接 (opens new window)

这题头脑一热自己写了一半,然后发现写的太麻烦了。

先上代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     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==NULL) return root2;
        if(root2==NULL) return root1;

        root1->val+=root2->val;
        root1->left =mergeTrees(root1->left,root2->left);
        root1->right =mergeTrees(root1->right,root2->right);
        return root1;

    }
};

递归三部曲:

1、确定参数和返回值

返回的应该是个树的根节点,然后参数是两个未合并的树。

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

2、确定终止条件

如果两个树遍历节点任意为空,就返回另一个节点

其中也包含两个均为空的情况,但这种情况是返回NULL,所以也是一样的。

if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2
if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1

3、单层递归逻辑

这时候逻辑就是都不为空的情况,所以先把t1和t2的值和到t1中,然后将左子树和右子树进行递归,参数就是t1和t2的子树。

t1->val += t2->val;                             // 中
        t1->left = mergeTrees(t1->left, t2->left);      // 左
        t1->right = mergeTrees(t1->right, t2->right);   // 右
        return t1;

三、二叉搜索树的搜索

力扣题目地址 (opens new window)

这道题利用二叉搜索树的特性还是蛮简单的,所以就先写了一遍。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     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* searchBST(TreeNode* root, int val) {
        if(root==NULL){
            return NULL;
        }
        if(root->val==val){
            return root;
        }
        else if(root->val>val){
            return searchBST(root->left,val);
        }
        else{
            return searchBST(root->right,val);
        }

    }
};

看了一遍题解发现是把前两种情况合并了,但思路是一样的,依然还是递归三部曲走一下:

1、确定函数的参数和返回值

题目要求返回子树所以返回搜索数值所在的节点。参数就是根节点和所要搜索的数值。

TreeNode* searchBST(TreeNode* root, int val)

2、确定终止条件

只要是遇到空节点和所需要的节点,就返回该节点(其实和我上面的逻辑是一样的,只是更优化,逻辑上root为空时返回的也是不存在的空,所以是一种情况)

if (root == NULL || root->val == val) return root;

3、单层递归逻辑

这里题解是先设了一个结果变量,将两种i情况的解放在了result中,这样更直观吧,我是直接在两种情况中就直接返回了(其实和题解整体代码的第二版一样)。

TreeNode* result = NULL;
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) {
        TreeNode* node =root;
        while(1){
            if(node==NULL||node->val==val){
                return node;
            }
            else if(node->val>val){
                node=node->left;
            }
            else{
                node=node->right;
            }

        }

    }
};

还是自己尝试写了一遍,然后看题解发现太麻烦了,emmmm其实逻辑是一样的,只是我的循环条件是恒成立的,而题解的循环条件我是依据迭代的题解在循环中处理了。

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;
    }
};

四、验证二叉搜索树

力扣题目链接 (opens new window)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     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:
    vector<int> vec;
    void traversal(TreeNode* node){
        if(node==NULL) return;
        traversal(node->left);
        vec.push_back(node->val);
        traversal(node->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;
        
    }
};

刚自己写半天发现陷进陷阱。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     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:
   long long maxval =LONG_MIN;
    bool isValidBST(TreeNode* root) {
        if(root==NULL) return true;
        bool left =isValidBST(root->left);
        if(maxval<root->val) maxval = root->val;
        else return false;
        bool right =isValidBST(root->right);
        return left&&right;
        

    }
};

这是递归的代码,主要思路是利用中序遍历,使maxval从最左侧节点比较,是否小于右侧的值。

迭代则是中序稍加改动

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

                cur = cur->right;               // 右
            }
        }
        return true;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值