Given a Binary Search Tree (BST) with root node root, and a target value V, split the tree into two subtrees where one subtree has nodes that are all smaller or equal to the target value, while the other subtree has all nodes that are greater than the target value.  It's not necessarily the case that the tree contains a node with value V.

Additionally, most of the structure of the original tree should remain.  Formally, for any child C with parent P in the original tree, if they are both in the same subtree after the split, then node C should still have the parent P.

You should output the root TreeNode of both subtrees after splitting, in any order.

Example 1:

Input: root = [4,2,6,1,3,5,7], V = 2
Output: [[2,1],[4,3,6,null,null,5,7]]
Explanation:
Note that root, output[0], and output[1] are TreeNode objects, not arrays. The given tree [4,2,6,1,3,5,7] is represented by the following diagram: 4
/ \
2 6
/ \ / \
1 3 5 7 while the diagrams for the outputs are: 4
/ \
3 6 and 2
/ \ /
5 7 1

Note:

  1. The size of the BST will not exceed 50.
  2. The BST is always valid and each node's value is different.

这道题给了我们一棵二叉搜索树Binary Search Tree,又给了我们一个目标值V,让我们将这个BST分割成两个子树,其中一个子树所有结点的值均小于等于目标值V,另一个子树所有结点的值均大于目标值V。这道题最大的难点在于不是简单的将某条边断开就可以的,不如题目中给的那个例子,目标值为2,我们知道要断开结点2和结点4的那条边,但是以结点2为root的子树中是有大于目标值2的结点的,而这个结点3必须也从该子树中移出,并加到较大的那个子树中去的。为了具体的讲解这个过程,这里借用官方解答贴中的例子来说明问题吧。

比如对于上图,假如root结点小于V,而root.right大于V的话,那么这条边是要断开的,但是如果root.right的左子结点(结点A)是小于V的,那么其边也应该断开,如果如果root.right的左子结点的右子结点(结点B)大于V,则这条边也应该断开,所以总共有三条边需要断开,如图中蓝色虚线所示,三条粗灰边需要断开,粉细边和绿细边是需要重新连上的边。那么我们应该如何知道连上哪条边呢?不要急,听博主慢慢道来。

博主告诉你们个秘密(一般人我不告诉他),对于树的题目,二话别说,直接上递归啊,除非是有啥特别要求,否则递归都可以解。而递归的精髓就是不断的DFS进入递归函数,直到递归到叶结点,然后回溯,我们递归函数的返回值是两个子树的根结点,比如对结点A调用递归,返回的第一个是A的左子结点,第二个是结点B,这个不需要重新连接,那么当回溯到root.right的时候,我们就需要让root.right结点连接上结点B,而这个结点B是对结点A调用递归的返回值中的第二个。如果是在左边,其实是对称的,root.left连接上调用递归返回值中的第一个,这两个想通了后,代码就不难谢啦,参见代码如下:

class Solution {
public:
vector<TreeNode*> splitBST(TreeNode* root, int V) {
vector<TreeNode*> res{NULL, NULL};
if (!root) return res;
if (root->val <= V) {
res = splitBST(root->right, V);
root->right = res[];
res[] = root;
} else {
res = splitBST(root->left, V);
root->left = res[];
res[] = root;
}
return res;
}
};

类似题目:

Delete Node in a BST

参考资料:

https://leetcode.com/problems/split-bst/solution/

https://leetcode.com/problems/split-bst/discuss/113798/C++Easy-recursion-in-O(n)

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Split BST 分割二叉搜索树的更多相关文章

  1. BST(二叉搜索树)的基本操作

    BST(二叉搜索树) 首先,我们定义树的数据结构如下: public class TreeNode { int val; TreeNode left; TreeNode right; public T ...

  2. 【JavaScript】Leetcode每日一题-二叉搜索树的范围和

    [JavaScript]Leetcode每日一题-二叉搜索树的范围和 [题目描述] 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和. 示例1: 输入: ...

  3. 【python】Leetcode每日一题-二叉搜索树节点最小距离

    [python]Leetcode每日一题-二叉搜索树节点最小距离 [题目描述] 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 . 示例1: 输入:root = [4 ...

  4. LeetCode.938-范围内求二叉搜索树节点值之和(Range Sum of BST)

    这是悦乐书的第359次更新,第386篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第221题(顺位题号是938).给定二叉搜索树的根节点,返回节点值在[L,R]之间的所有 ...

  5. [LeetCode]96. 不同的二叉搜索树(DP,卡特兰数)

    题目 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ ...

  6. Leetcode 96. 不同的二叉搜索树

    题目链接 https://leetcode.com/problems/unique-binary-search-trees/description/ 题目描述 给定一个整数 n,求以 1 ... n ...

  7. LeetCode动画 | 1038. 从二叉搜索树到更大和树

    今天分享一个LeetCode题,题号是1038,标题是:从二分搜索树到更大和数. 题目描述 给出二叉搜索树的根节点,该二叉树的节点值各不相同,修改二叉树,使每个节点 node 的新值等于原树中大于或等 ...

  8. [CareerCup] 4.6 Find Next Node in a BST 寻找二叉搜索树中下一个节点

    4.6 Write an algorithm to find the'next'node (i.e., in-order successor) of a given node in a binary ...

  9. LeetCode 95——不同的二叉搜索树 II

    1. 题目 2. 解答 以 \(1, 2, \cdots, n\) 构建二叉搜索树,其中,任意数字都可以作为根节点来构建二叉搜索树.当我们将某一个数字作为根节点后,其左边数据将构建为左子树,右边数据将 ...

随机推荐

  1. [Android] Android 锁屏实现与总结 (一)

    实现锁屏的方式有多种(锁屏应用.悬浮窗.普通Activity伪造锁屏等等).但国内比较主流并且被广泛应用的Activity伪造锁屏方式. 实例演示图片如下: 系列文章链接如下: [Android] A ...

  2. 关于缓存和 Chrome 的“新版刷新”

    在读本文前你要确保读过我的上篇文章<扼杀 304,Cache-Control: immutable>,因为本文是接着上文写的.上文说到,在现代 Web 上,“条件请求/304 响应”绝大多 ...

  3. 深入浅出UE4网络

    UE4中的官方文档结构比较混乱,且有部分错误,不方便学习.笔者试图通过本文,整理出一篇关于UE4网络的文章,方便朋友们对UE4中的网络同步部分的认识,并有进一步理解.如有讲得不清楚明白的地方,还望批评 ...

  4. 【汇总目录】C#

    [2019年04月29日] C# textbox 自动滚动 [2019年02月07日] C#利用VUDP.cs开发网络通讯应用程序 [2019年02月06日] C#利用VINI.cs操作INI文件 [ ...

  5. 计算int数组中的最大,最小,平均值

    public static void testNumber(int[] arr) { int max = arr[0]; int min = arr[0]; int avg = 0; int sum ...

  6. 用WKWebView 截取整个Html页面

    以前使用UIWebview时,想截取整个页面,可以调整内部scrollView的frame,之后调用 scrollView的layer的 render 方法,很方便. 但是在WKWebView上,行不 ...

  7. Java_Character类

      Character类用于对单字符进行操作. 常用的方法: System.out.println(Character.isDigit('1')); // true 判断是否是一个数字字符 Syste ...

  8. AD证书导入文档(单向认证)

    AD证书或者SSL证书导入的方法步骤(在root用户下操作) 1.  将证书命名为AD-PRO.cer,并确定证书的颁发. 2.  将/app/ad_cert/keystore下的原有证书删除掉和文件 ...

  9. golang mysql 的 packet sequence error 这个错

    在公司用golang 写了个插入外链数据的服务,这服务是2016年写的,大概作用就是,python 爬取的数据,要同步到 wordpress中,golang就负责,将数据整理,图片下载弄到 wordp ...

  10. 如何在cocos中为节点添加监听事件

    一般在监听键盘事件时,可是采用以下方式来监听键盘事件: 以及记得定义取消监听的函数(这个摧毁函数会自己调用吗?): 同时这里还有一种传统的监听方式: 但是cocos官方的文档建议我们不要使用这种方式, ...