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

LeetCode 654 最大二叉树

题目链接:654
思路:先从数组中找到最大值,构造根节点,再分别递归左侧数组和右侧数组,构造左子树和右子树。
代码:

/**
 * 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) {
        if (nums.size() == 0) return NULL;

        vector<int>::iterator max_it = max_element(nums.begin(), nums.end());
        TreeNode* root = new TreeNode(*max_it);

        vector<int> left(nums.begin(), max_it);
        vector<int> right(max_it+1, nums.end());
        root->left = constructMaximumBinaryTree(left);
        root->right = constructMaximumBinaryTree(right);
        return root;
    }
};

LeetCode 617 合并二叉树

题目链接:617

递归 未参考版本

思路:采用前序遍历,先合并中间节点,再合并左右子树
代码:

/**
 * 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 && !root2) return NULL;

        TreeNode* root = new TreeNode();
        if (!root1 && root2) {
            root->val = root2->val;
            root->left = mergeTrees(NULL, root2->left);
            root->right = mergeTrees(NULL, root2->right);
        }
        else if (root1 && !root2) {
            root->val = root1->val;
            root->left = mergeTrees(root1->left, NULL);
            root->right = mergeTrees(root1->right, NULL);
        } 
        else {
            root->val = root1->val + root2->val; 
            root->left = mergeTrees(root1->left, root2->left);
            root->right = mergeTrees(root1->right, root2->right);
        } 
        return root;
    }
};

递归

思路:采用前序遍历,先合并中间节点,再合并左右子树。当左右子树一个为空,则无需继续递归合并,因为合并后一定等于非空树,直接返回非空树即可。
代码:

/**
 * 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) return root2;
        if (!root2) return root1;

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

迭代

思路:采用层序遍历,将两个树的节点同时加入队列。一次弹出两个节点,当两个节点的左节点都非空,则一起压入队列,否则,直接等于非空节点。右节点同理。
代码:

/**
 * 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) return root2;
        if (!root2) return root1;

        queue<TreeNode*> que;
        que.push(root1);
        que.push(root2);
        while (!que.empty()) {
            TreeNode* node1 = que.front();
            que.pop();
            TreeNode* node2 = que.front();
            que.pop();

            node1->val = node1->val + node2->val;
            if (node1->left && node2->left) {
                que.push(node1->left);
                que.push(node2->left);
            } 
            if (node1->right && node2->right) {
                que.push(node1->right);
                que.push(node2->right);
            } 
            if (!node1->left && node2->left) node1->left = node2->left;
            if (!node1->right && node2->right) node1->right = node2->right;
        }
        return root1;
    }
};

LeetCode 700 二叉搜索树中的搜索

题目链接:700

递归

思路:只需根据当前节点与目标的大小,选择向左或向右递归即可
代码:

/**
 * 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) return NULL;
        TreeNode* result;
        if (root->val == val) result = root;
        if (root->val < val) result = searchBST(root->right, val);
        if (root->val > val) result = searchBST(root->left, val);
        return result;
    }
};

迭代

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

LeetCode 98 验证二叉搜索树

递归 未参考

思路:前序遍历,先判断左子树中的最大值是否小于当前节点,再递归左子树判断是否是二叉搜索;右子树同理。
代码:

/**
 * 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:
    bool isValidBST(TreeNode* root) {
        if (!root->left && !root->right) return true;

        bool valid_left = true, valid_right = true;
        if (root->left) {
            TreeNode* left = root->left;
            int left_max;
            while (left) {
                left_max = left->val;
                left = left->right;
            }
            valid_left = (left_max < root->val) && isValidBST(root->left);
        }
        if (root->right) {
            TreeNode* right = root->right;
            int right_min;
            while (right) {
                right_min = right->val;
                right = right->left;
            }
            valid_right = (right_min > root->val) && isValidBST(root->right);
        }

        return valid_left && valid_right;
    }
};

递归+数组

思路:利用二叉搜索树的性质:中序遍历递增。先中序遍历二叉树,将值存入数组,再判断数组是否递增。
代码:

/**
 * 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 recurse(TreeNode* root) {
        if (!root) return;
        recurse(root->left);
        vec.push_back(root->val);
        recurse(root->right);
    }

    bool isValidBST(TreeNode* root) {
        vec.clear();
        recurse(root);
        for (int i=1; i<vec.size(); ++i) {
            if (vec[i-1] >= vec[i]) 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:
    TreeNode* pre = NULL;
    bool isValidBST(TreeNode* root) {
        if (!root) return true;

        bool left = isValidBST(root->left);
        if (pre && pre->val >= root->val) return false;
        else pre = root;
        bool right = isValidBST(root->right);

        return left && right;
    }
};

迭代

思路:中序遍历迭代,同时判断与前一个节点的大小关系
代码:

/**
 * 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:
    bool isValidBST(TreeNode* root) {
        stack<TreeNode*> stk;
        TreeNode* cur = NULL;
        TreeNode* pre = NULL;

        if (root) stk.push(root);
        while (!stk.empty()) {
            cur = stk.top();
            stk.pop();

            if (cur) {
                if (cur->right) stk.push(cur->right);
                stk.push(cur);
                stk.push(NULL);
                if (cur->left) stk.push(cur->left);
            } else {
                cur = stk.top();
                stk.pop();
                if (pre && cur->val <= pre->val) return false;
                pre = cur;
            }
        }
        return true;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值