day17 || lc617合并二叉树 || lc654构造最大二叉树 || lc70二叉搜索树的搜素 || lc98验证二叉搜索树

day17

lc617_合并二叉树

给你两个二叉树 请你合并成一个二叉树 规则如下:

  1. 如果在相同的位置有节点 那么两个节点相加
  2. 不为 NULL 的节点将直接作为新二叉树的节点。

注意: 合并必须从两个树的根节点开始。

使用前序便利 跟 左 右

递归三部曲

  1. 返回值 返回合并之后的根节点 参数:: 两个树的跟节点
  2. 如果tree1遇到空 返回tree2 同理 t2遇到空 返回t1
  3. 单层逻辑(直接改变t1)
  • 如果两个都不为空 那么两个节点相加
  • 然后递归便利左子树 和 右子树

public Node mergeTrees(Node r1, Node r2){
    if(r1 == null) return r2;
    if(r2 == null) return r1;

    r1.v += r2.v;

    r1.l = mergeTrees(r1.l, r2.l);
    r1.r = mergeTrees(r1.r, r2,r);

    return r1;
}

lc654_构造最大的二叉树

给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

  • 二叉树的根是数组中的最大元素。
  • 左子树是通过数组中最大值左边部分构造出的最大二叉树。
  • 右子树是通过数组中最大值右边部分构造出的最大二叉树。

通过给定的数组构建最大二叉树,并且输出这个树的根节点。

凡是构造二叉树的题目 均要使用前序遍历 跟 左 右


假设给一个数组是 3 2 1 6 0 5

选择最大的元素6 作为跟节点 然后最大元素左区间继续构造左子树 规则还是一样 选取最大的作为跟节点 右区间同理


递归三部曲

  1. 返回最大的跟节点 参数传入数组
  2. 如果数组大小等于1 说明到了叶子节点 那么就返回终止 new Node
  3. 单层逻辑 (跟 左 右)
  • 找到最大值以及对应的下标 构造出跟节点
  • 构造左子树 要保证区间里面元素最少有一个元素 左区间的范围 0 - 最大值index
  • 右子树 范围是 index + 1 到 数组最后
  • 返回跟节点

public Node constructMaximumBinaryTree1(int[] nums, int leftIndex, int rightIndex) {
    return digui(nums, 0, nums.length);

}


private Node digui(int[] nums, int lIndex, int rIndex) {
    if(rIndex - lIndex < 1) return null;  //小于一说明没有元素了

    if(rIndex - lIndex == 1) return new Node(nums[lIndex]); // 说明只有一个元素

    int maxIndex = lIndex; //假设最大值的下标
    int maxVal = nums[maxIndex]; //假设最大值
    for(int i = lIndex + 1; i < rIndex; i++){ // 找最大值
        if(nums[i] > maxVal){
            maxVal = nums[i];
            maxIndex = i;

        }
    }
    Node root = new Node(maxVal);  //根据最大值构造跟节点
    root.l = digui(nums, lIndex, maxIndex);
    root.r = digui(nums, maxIndex + 1, rIndex);
    return root;

}


lc700_二叉搜索数中的搜索

给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。

二叉搜索树是什么?

  1. 如果左子树不为空, 则左子树上的所有节点的值 都小于 他的跟节点的值
  2. 如果右子树不为空, 右子树上的所有节点上的值 都大于 他的跟节点
  3. 他的左右子树 也分别上二叉搜索树

跟节点大于左子树所有节点 小于右子树所有的节点


本题根据这个规律 不用确定前中后便利顺序 根据规律就好

如果要搜索的值要是 小于 跟节点的值 说明要搜索的值 在左子树 就要去左子树去便利

大于 跟节点 说明在 右子树 就去右子树遍历


public static Node searchBST(Node root, int target){
    if(root == null || root.v == target) return root;

    //如果要搜索的值要是 小于 跟节点的值 说明要搜索的值 在左子树
    //反之 在右子树
    if(target < root.v) return searchBST(root.l, target);
    else return searchBST(root.r, target);

}

lc98_验证二叉搜索树

给你一个二叉树的根节点 <font style="color:rgba(38, 38, 38, 0.75);background-color:rgb(240, 240, 240);">root</font> ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

遇到 搜索树,一定想着中序遍历,这样才能利用上特性。 是不是单调递增的

package day17;


/**
 * 98. 验证二叉搜索树--中等
 *
 */
public class Lc98_isValidBST {
    Node max;


    public boolean isValidBST(Node root) {
        if(root == null) return true;

        //左
        boolean left = isValidBST(root.l);
        //跟
        if(max != null && root.v <= max.v) return false;
        max = root;
        //右
        boolean right = isValidBST(root.r);

        return right;
        
    }


}

posted @ 2024-11-20 19:40  小杭呀  阅读(8)  评论(0)    收藏  举报