二叉搜索树

530. 二叉搜索树的最小绝对差(783题一样)
给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。

示例 1:
在这里插入图片描述

输入:root = [4,2,6,1,3]
输出:1

示例 2:
在这里插入图片描述

输入:root = [1,0,48,null,null,12,49]
输出:1
解析过程:

/**
 * 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 {
    List<Integer> list=new ArrayList<>();
    public int getMinimumDifference(TreeNode root) {
        //先中序遍历,然后求差
        if(root == null){
            return 0;
        }
        InOrder(root);
        int value=Integer.MAX_VALUE;
        for(int i=1;i<list.size();i++){
            value=Math.min(value,list.get(i)-list.get(i-1));
        }
        return value;
    }
    
    public void InOrder(TreeNode root){
        if(root == null){
            return;
        }
        InOrder(root.left);
        list.add(root.val);
        InOrder(root.right);
    }
}

结果:
执行用时:1 ms, 在所有 Java 提交中击败了46.33%的用户
内存消耗:38.9 MB, 在所有 Java 提交中击败了14.61%的用户
通过测试用例:188 / 188

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

    4
   / \
  2   7
 / \
1   3

和值: 2
你应该返回如下子树:

  2     
 / \   
1   3

在上述示例中,如果要找的值是 5,但因为没有节点值为 5,我们应该返回 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){
            return null;
        }
        if(root.val == val){
            return root;
        }else if(root.val > val){
            return searchBST(root.left,val);
        }else {
            return searchBST(root.right,val);
        }
        
    }
}

结果:
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:38.9 MB, 在所有 Java 提交中击败了95.56%的用户
通过测试用例:36 / 36

701. 二叉搜索树中的插入操作
给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。
注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。
示例 1:
在这里插入图片描述

输入:root = [4,2,7,1,3], val = 5
输出:[4,2,7,1,3,5]

示例 2:
输入:root = [40,20,60,10,30,50,70], val = 25
输出:[40,20,60,10,30,50,70,null,null,25]
示例 3:
输入:root = [4,2,7,1,3,null,null,null,null,null,null], val = 5
输出:[4,2,7,1,3,5]
解析过程:

/**
 * 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 insertIntoBST(TreeNode root, int val) {
        //可以先通过二分查找的方式找到需要插入的位置
        if(root == null){
            return new TreeNode(val);
        }
        TreeNode node=root;
        while(node != null){
            //如果节点值小于新值,在右子树上查找
            if(node.val < val){
                if(node.right == null){
                    node.right= new TreeNode(val);
                    break;
                }else{
                    node = node.right;
                }
            }else {
                if(node.left == null){
                    node.left=new TreeNode(val);
                    break;
                }else {
                    node=node.left;
                }
            }
           
        }
                
        return root;
    }
}

结果:
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:39 MB,在所有 Java 提交中击败了65.23%的用户
通过测试用例:35 / 35

98. 验证二叉搜索树
(与面试题04.05.合法二叉树一样)
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

示例 1:
在这里插入图片描述

输入:root = [2,1,3]
输出:true
示例 2:
在这里插入图片描述
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。
解析过程:
方法一:
递归

/**
 * 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) {
        //时间复杂度和空间复杂度都为O(n)
        return isValidT(root,Long.MIN_VALUE,Long.MAX_VALUE);
    }
    public boolean isValidT(TreeNode root,long low,long high){
        //递归DFS
        //左子树的节点需要保证小于根节点,右子树的节点需要保证大于根节点
        if(root == null){
            return true;
        }
        //采用上界和下界到的思想
        if(root.val<=low ||root.val>=high){
            return false;
        }
        return isValidT(root.left,low,root.val) && isValidT(root.right,root.val,high);
    }
}

结果:
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:38.1 MB, 在所有 Java 提交中击败了53.28%的用户
通过测试用例:80 / 80
方法二:
中序遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    //可以先中序遍历,并存入list,若有序,则为合法二叉搜索树;否则,返回false
    public boolean isValidBST(TreeNode root) {
        if(root == null){
            return true;
        }
        List<Integer> list=new ArrayList<>();
        Inorder(root,list);
        for(int i=0;i<list.size()-1;){
            if(list.get(i)<list.get(i+1)){
                i++;
            }else {
                return false;
            }
        }
        return true;
    }
    //中序遍历
    public void Inorder(TreeNode node,List<Integer> list){
        if(node == null){
            return;
        }
        Inorder(node.left,list);
        list.add(node.val);
        Inorder(node.right,list);
    }
}

结果:
执行用时:2 ms, 在所有 Java 提交中击败了22.97%的用户
内存消耗:38.2 MB, 在所有 Java 提交中击败了19.21%的用户
通过测试用例:75 / 75

653. 两数之和 IV - 输入 BST
给定一个二叉搜索树 root 和一个目标结果 k,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。
示例 1:
在这里插入图片描述

输入: root = [5,3,6,2,4,null,7], k = 9
输出: true
示例 2:
在这里插入图片描述

输入: root = [5,3,6,2,4,null,7], k = 28
输出: false

示例 3:
输入: root = [2,1,3], k = 4
输出: true

示例 4:
输入: root = [2,1,3], k = 1
输出: false
示例 5:
输入: root = [2,1,3], k = 3
输出: 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 findTarget(TreeNode root, int k) {
        //HashSet<>
        //a+b=k,a为已知在树上的节点,找b是否存在。在遍历过程中,将每个节点的值都放到一个set 中。如果遍历完整棵树都没有找到一对节点和为 k,那么该树上不存在两个和为k 的节点
        Set<Integer> set=new HashSet<>();
        return Help(root,k,set);

    }
    public boolean Help(TreeNode root,int k,Set<Integer> set){
        if(root == null){
            return false;
        }
        //对于每个值为a 的节点,在 set 中检查是否存在 k-a。如果存在,那么可以在该树上找到两个节点的和为 k
        if(set.contains(k-root.val)){
            return true;
        }else{
            //否则,将a放入到set 中
            set.add(root.val);
        }
        //在树的每个节点上遍历它的两棵子树(左子树和右子树),寻找另外一个匹配的数
        return Help(root.left,k,set) ||Help(root.right,k,set);
    }
}

结果:
执行用时:2 ms, 在所有 Java 提交中击败了97.72%的用户
内存消耗:39.3 MB, 在所有 Java 提交中击败了58.63%的用户
通过测试用例:422 / 422

方法二:

/**
 * 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 findTarget(TreeNode root, int k) {
        //List<>
        //首尾指针
        List<Integer> list=new ArrayList<>();
        Inorder(root,list);
        int le=0,ri=list.size()-1;
        while(le<ri){
            int sum=list.get(le)+list.get(ri);
            if(sum == k){
                return true;
            }else if(sum < k){
                le++;
            }else {
                ri--;
            }
        }
        return false;
    }
    //中序遍历
    public void Inorder(TreeNode root,List<Integer> list){
        if(root == null){
            return;
        }
        Inorder(root.left,list);
        list.add(root.val);
        Inorder(root.right,list);
    }
}

结果:
执行用时:2 ms, 在所有 Java 提交中击败了97.72%的用户
内存消耗:39.6 MB, 在所有 Java 提交中击败了38.46%的用户
通过测试用例:422 / 422

方法三:

/**
 * 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 {
    //暴力解法  依次遍历每个节点,看是否存在相加之和等于k
    List<Integer> list=new ArrayList<>();
    public boolean findTarget(TreeNode root, int k) {
        Inorder(root);
        for(int i=0;i<list.size()-1;i++){
            for(int j=i+1;j<list.size();j++){
                if(list.get(i)+list.get(j)==k){
                    return true;
                }
            }
        }
        return false;
    }
    public void Inorder(TreeNode node){
        if(node==null){
            return;
        }
        Inorder(node.left);
        list.add(node.val);
        Inorder(node.right);
    }
}

结果:
执行用时:12 ms, 在所有 Java 提交中击败了8.55%的用户
内存消耗:39.5 MB, 在所有 Java 提交中击败了40.89%的用户
通过测试用例:424 / 424

235. 二叉搜索树的最近公共祖先
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
说明:
所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉搜索树中。
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
在这里插入图片描述

示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
示例 2:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
解析过程:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //需要判断两个节点的位置
        /*1.如果当前节点的值大于p、q的值,说明p、q在当前节点的左子树上
          2.如果当前节点的值小于p、q的值,说明p、q在当前节点的右子树上
          3.如果当前节点的值不满足上述两条要求,那么说明当前节点就是「分岔点」。此时,pp 和 qq 要么在当前节点的不同的子树中,要么其中一个就是当前节点。
         */
        TreeNode Ancestor=root;
        while(true){
            if(Ancestor.val > p.val && Ancestor.val > q.val){
                Ancestor=Ancestor.left;
            }else if(Ancestor.val < p.val && Ancestor.val < q.val){
                Ancestor=Ancestor.right;
            }else {
                break;
            }
        }
        return Ancestor;
    }
}

结果:
执行用时:6 ms, 在所有 Java 提交中击败了56.19%的用户
内存消耗:39.1 MB, 在所有 Java 提交中击败了81.38%的用户
通过测试用例:27 / 27

96. 不同的二叉搜索树
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
提示:1 <= n <= 19

示例 1:
在这里插入图片描述
输入:n = 3
输出:5

示例 2:
输入:n = 1
输出:1
解析过程:

class Solution {
    public int numTrees(int n) {
      //n个节点存在的二叉搜索树的种类数是dp(n),第i个节点的二叉搜索树种类为dp(i)=dp(i-1)*dp(n-i)
      //dp(n)=dp(0)*dp(n-1)+dp(1)*dp(n-2)+...+dp(n-1)*dp(0)
      //卡特兰数:Cn+1=C0*Cn+C1*Cn-1+...+Cn*C0
     
        int[] dp=new int[n+1];
        //边界值
        dp[0]=1;
        dp[1]=1;
        
        //dp[3]=dp[0]*dp[2]+dp[1]*dp[1]+dp[2]*dp[0]
        for(int i=2;i<n+1;++i){
            for(int j=1;j<i+1;++j){
                dp[i] += dp[j-1]*dp[i-j];
            }
        }
        return dp[n];
    }
}

结果:
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:35.2 MB, 在所有 Java 提交中击败了48.78%的用户
通过测试用例:19 / 19

95. 不同的二叉搜索树 II
给你一个整数 n ,请你生成并返回所有由 n 个节点组成且节点值从 1 到 n 互不相同的不同 二叉搜索树 。可以按 任意顺序 返回答案。
提示:1 <= n <= 8

示例 1:
在这里插入图片描述

输入:n = 3
输出:[[1,null,2,null,3],[1,null,3,2],[2,1,3],[3,1,null,null,2],[3,2,null,1]]

示例 2:
输入:n = 1
输出:[[1]]
解析过程:

/**
 * 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 List<TreeNode> generateTrees(int n) {
        //从i=0到n的节点分别为根节点来讨论,当节点i为根节点时,左子树的节点值的集合为[1…i−1],右子树的节点值的集合为[i+1…n],将该问题变成缩短范围的问题
        if(n==0){
            return new ArrayList<TreeNode>();
        }
        return generate(1,n);
    }
    public List<TreeNode> generate(int s,int e){
        List<TreeNode> list=new ArrayList<TreeNode>();
        if(s>e){
            list.add(null);
            return list;
        }
        
        //遍历
        for(int i=s;i<=e;i++){
            //获得可行的左子树集合
            List<TreeNode> leftTree=generate(s,i-1);
            //右子树集合
            List<TreeNode> rightTree=generate(i+1,e);
            for(TreeNode le:leftTree){
                for(TreeNode ri:rightTree){
                    TreeNode cur=new TreeNode(i);
                    cur.left=le;
                    cur.right=ri;
                    list.add(cur);
                }
            }
        }
        return list;
    }
}

结果:
执行用时:1 ms, 在所有 Java 提交中击败了99.01%的用户
内存消耗:39 MB, 在所有 Java 提交中击败了62.11%的用户
通过测试用例:8 / 8

99. 恢复二叉搜索树
给你二叉搜索树的根节点 root ,该树中的两个节点被错误地交换。请在不改变其结构的情况下,恢复这棵树。
进阶:使用 O(n) 空间复杂度的解法很容易实现。你能想出一个只使用常数空间的解决方案吗?

示例 1:
在这里插入图片描述

输入:root = [1,3,null,null,2]
输出:[3,1,null,null,2]
解释:3 不能是 1 左孩子,因为 3 > 1 。交换 1 和 3 使二叉搜索树有效。
示例 2:
在这里插入图片描述

输入:root = [3,1,4,null,null,2]
输出:[2,1,4,null,null,3]
解释:2 不能在 3 的右子树中,因为 2 < 3 。交换 2 和 3 使二叉搜索树有效。
解析过程:

/**
 * 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 void recoverTree(TreeNode root) {
        //需要一个数组,将遍历后的节点存入数组中
        List<TreeNode> list=new ArrayList<>();
        
        if(root ==null){
            return;
        }
        BST(root,list);
        TreeNode n1=null;
        TreeNode n2=null;
        //遍历数组,找出顺序不一致的两个节点,并进行替换
        for(int i=0;i<list.size()-1;++i){
            for(int j=i+1;j<list.size();++j){
                if(list.get(i).val>list.get(j).val){
                    n2=list.get(j);
                    if(n1==null){
                        n1=list.get(i);
                    }
                }
            }
        }
        if(n1!=null && n2!=null){
            int temp=n1.val;
            n1.val=n2.val;
            n2.val=temp;
        }
    }
    //因为中序遍历所得到的结果是有序的,因此进行中序遍历
    public void BST(TreeNode root,List<TreeNode> list){
        if(root == null){
            return;
        }
        BST(root.left,list);
        list.add(root);
        BST(root.right,list);
    }
}

结果:
执行用时:5 ms, 在所有 Java 提交中击败了6.01%的用户
内存消耗:38.6 MB, 在所有 Java 提交中击败了76.40%的用户
通过测试用例:1919 / 1919
补充:

for(int i=0;i<list.size()-1;++i){
            if(list.get(i).val>list.get(i+1).val){
                n2=list.get(i+1);
                if(n1==null){
                    n1=list.get(i);
                }
            }
        }

将双重for循环进行修改,执行用时更少一些
结果:
执行用时:3 ms, 在所有 Java 提交中击败了47.39%的用户
内存消耗:38.6 MB, 在所有 Java 提交中击败了81.31%的用户
通过测试用例:1919 / 1919

1382. 将二叉搜索树变平衡
给你一棵二叉搜索树,请你返回一棵 平衡后 的二叉搜索树,新生成的树应该与原来的树有着相同的节点值。
如果一棵二叉搜索树中,每个节点的两棵子树高度差不超过 1 ,我们就称这棵二叉搜索树是 平衡的 。
如果有多种构造方法,请你返回任意一种。

示例:
在这里插入图片描述
在这里插入图片描述

输入:root = [1,null,2,null,3,null,4,null,null]
输出:[2,1,3,null,null,null,4]
解释:这不是唯一的正确答案,[3,1,4,null,2,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 balanceBST(TreeNode root) {
        if(root==null){
            return null;
        }
        List<Integer> list=new ArrayList<>();
        Inorder(root,list);
        return BST(list,0,list.size()-1);
    }
    //1.先中序遍历
    public void Inorder(TreeNode node,List<Integer> list){
        if(node==null){
            return;
        }
        Inorder(node.left,list);
        list.add(node.val);
        Inorder(node.right,list);
    }
    //2.用二分法构建二叉搜索树
    public TreeNode BST(List<Integer> list,int Left,int Right){
        if(Left>Right){
            return null;
        }
        int mid=(Left+Right)/2;
        TreeNode NewRoot=new TreeNode(list.get(mid));
        NewRoot.left=BST(list,Left,mid-1);
        NewRoot.right=BST(list,mid+1,Right);
        return NewRoot;
    }
}

结果:
执行用时:3 ms, 在所有 Java 提交中击败了28.95%的用户
内存消耗:41.8 MB, 在所有 Java 提交中击败了50.27%的用户
通过测试用例:17 / 17

108. 将有序数组转换为二叉搜索树
给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

示例 1:
在这里插入图片描述

输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:
在这里插入图片描述

示例 2:
在这里插入图片描述

输入:nums = [1,3]
输出:[3,1]
解释:[1,3] 和 [3,1] 都是高度平衡二叉搜索树。
解析过程:

/**
 * 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 sortedArrayToBST(int[] nums) {
       
        return BST(nums,0,nums.length-1);
    }
    public TreeNode BST(int[] nums,int Left,int Right){
        //选择数组的中间位置左边的数字作为根节点
        if(Left>Right){
            return null;
        }
        int mid=(Left+Right)/2;
        TreeNode root=new TreeNode(nums[mid]);
         //递归
        root.left= BST(nums,Left,mid-1);
        root.right= BST(nums,mid+1,Right);
        return root;
    }
}

结果:
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:38.2 MB, 在所有 Java 提交中击败了46.73%的用户
通过测试用例:31 / 31
调试:

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        int[] nums={-10,-3,0,5,9};
        TreeNode bst = new LeetCode108().sortedArrayToBST(nums);
        //遍历bst,输出(此处是先序遍历)
        List<Integer> list=new Leetcode144().preorderTraversal(bst);
        for(int i=0;i<list.size();i++){
            System.out.println(list.get(i));
        }

    }
}

结果:
在这里插入图片描述
109. 有序链表转换二叉搜索树
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:
给定的有序链表: [-10, -3, 0, 5, 9],
一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:

    0
     / \
   -3   9
   /   /
 -10  5

解析过程:
与108题类似

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
/**
 * 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 sortedListToBST(ListNode head) {
        return BST(head,null);
    }
    //寻找根节点
    public TreeNode BST(ListNode left,ListNode right){
        if(left == right){
            return null;
        }
        ListNode mid=Mid(left,right);
        TreeNode root=new TreeNode(mid.val);
        //区间左闭右开
        root.left=BST(left,mid);
        root.right=BST(mid.next,right);
        return root;
    }
    //链表寻找中位数节点,用快慢指针方法
    public ListNode Mid(ListNode left,ListNode right){
        ListNode fast=left;
        ListNode slow=left;
        while(fast != right && fast.next != right){
            fast=fast.next.next;
            slow=slow.next;
        }
        return slow;
    }
}

结果:
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:39.7 MB, 在所有 Java 提交中击败了29.06%的用户
通过测试用例:32 / 32

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值