代码随想录训练营Day19树:654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

LeetCode654最大二叉树

思路:找到最大的座位父节点,左边看作左子树,右边看作右子树。递归实现。
关键点:数组的左闭右闭

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return construct(nums, 0, nums.length-1);

    }
    public TreeNode construct(int[] nums, int left, int right){
        if(right - left < 0){
            return null;
        }
        int max = 0;
        int index = left;
        for(int i=left;i<=right;i++){
            if(nums[i]>max){
                max = nums[i];
                index = i;
            }
        }
        TreeNode root = new TreeNode(max);
        root.left = construct(nums, left, index-1);
        root.right = construct(nums, index+1, 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 {

private:
    TreeNode* traversal(vector<int>& nums){
        if(nums.size() == 0) return NULL;

        int index = 0;
        int temp = 0;
        for(int i=0;i<nums.size();i++){
            if(nums[i] > temp){
                temp = nums[i];
                index = i;
            }
        }
        int nodevalue = nums[index];
        TreeNode* node = new TreeNode(nodevalue);
        vector<int> left(nums.begin(), nums.begin()+index);
        vector<int> right(nums.begin()+index+1, nums.end());

        node->left = traversal(left);
        node->right = traversal(right);

        return node;

    }

public:
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        if(nums.size() == 0) return NULL;
        return traversal(nums);
    }
};

LeetCode617合并二叉树

关键点:不用考虑数值和null相加的情况。因为在其中一个为null时,直接返回另一个子树。不用考虑后面了。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.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; // 不需要再新建一个root了 直接覆盖到root1即可。
        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) {
        // 最巧妙地地方就是当root1 为NULL 直接返回root2的值;
        // 如果root2为NULL 直接返回root1的值
        
        if(root1 == NULL) return root2;
        if(root2 == NULL) return root1;

        int sum = root1->val + root2->val;
        TreeNode* root = new TreeNode(sum);
        root->left = mergeTrees(root1->left, root2->left);
        root->right = mergeTrees(root1->right, root2->right);
        return root;
    }
};

LeetCode700二叉搜索树中的搜索

二叉搜索树(Binary Search Tree,BST)是一种特殊的二叉树,它具有以下性质:

  1. 对于任意一个节点,它的左子树中的所有节点的值都小于它的值,而它的右子树中的所有节点的值都大于它的值。
  2. 左子树和右子树也都是二叉搜索树。

基于这个性质,我们可以利用二叉搜索树进行快速的查找、插入和删除等操作,时间复杂度通常为 O(log n)。

思路:

  • 对于普通二叉树:
    • 先找父节点,如果父节点是,就返回;
    • 在找左节点,如果左节点返回的是null,就没有,返回不为null,就直接返回
    • 最后找右节点。
  • 对于二叉搜索树:
    • 可判断root.val和val的大小关系,转到左子树或右子树。
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        // 在普通树中还是需要考虑遍历顺序:这里是前序
        if(root == null || root.val == val){//如果到了空,或者root就是val的时候就返回
            return root;
        }
        TreeNode left = searchBST(root.left, val);// 父节点不是就先看左子树
        if(left != null){// 如果左子树的返回值不是null那就是有target。
            return left;
        }
        return searchBST(root.right, val);// 左子树没有就在右子树找,找到就返回root,找不到就返回null
    }
}
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null || root.val == val){
            return root;
        }
        if(root.val>val){
            return searchBST(root.left,  val);
        }
        else if(root.val<val){
            return searchBST(root.right, val);
        }
        return null;
    }
}

LeetCode98验证二叉搜索树

思路:按照中序遍历,将二叉树遍历到数组里。再检查数组是否递增。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    TreeNode max;
    public boolean isValidBST(TreeNode root) {
        // 中序遍历
        if(root == null){ // 空数也为true,如果,
            return true; 
        }
        boolean left = isValidBST(root.left); //左,
        if(left == false){  // 如果左边不符合则返回false
            return false;
        }
        if(max != null && max.val >=root.val){ // max 用来标记
            return false;
        }
        max = root;
        return isValidBST(root.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:
    long long max = LONG_MIN;  // 设置为全局变量,不能在递归里面设置。要保持这个值是最新的 
    bool isValidBST(TreeNode* root) {
        if(root==NULL) return true; // 空二叉树也是二叉搜索树

    
        // 充分利用二叉搜索树的性质:中序遍历
        bool left = isValidBST(root->left); // 左:left已经是下一步的返回值为 bool值

        if(max< root->val) max = root->val; // 中:比较当前的节点值,与上一步的max的值的大小,如果保持递增就是对的。这样就避免了之前代码的bug [5,4,6,null,null,3,7]
        else return false; // 遇到异常返回错误

        bool right = isValidBST(root->right);  // 右

        return left && right; // 判断左子树和右子树的交集
    }
};

双指针优化,更易理解。

思路:分别比较root和root.left;root和root.right。利用两个指针记录root的左右两侧,在递归。当出现左中右不递增的时候返回false,否则一直遍历到null返回true。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isValidBST(TreeNode root) {
        // 中序遍历+双指针优化
        long max = Long.MAX_VALUE;
        long min = Long.MIN_VALUE;
        return validBSt(min, max, root);
    }
    public boolean validBSt(long left, long right, TreeNode root){
        // 左<中<右
        // 两个指针分别对应root的左右,
        // 比较左子树时,观察root.val 和 root.left的大小
        // 比较右子树时,观察root.val 和 root.right的大小
        if(root == null){
            return true;
        }
        if(left>=root.val || right<=root.val){ // 左>=中  或者中>=右则false。
            return false;
        }
        boolean leftTree = validBSt(left, root.val, root.left);
        boolean rightTree = validBSt(root.val, right, root.right);
        return leftTree && rightTree;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值