Given a tree, rearrange the tree in in-order so that the leftmost node in the tree is now the root of the tree, and every node has no left child and only 1 right child.
```
Example 1:
Input: [5,3,6,2,4,null,8,1,null,null,null,7,9]

  5
/ \
3 6

/ \

2 4 8

 / /

1 7 9

Output: [1,null,2,null,3,null,4,null,5,null,6,null,7,null,8,null,9]

1



  2



  3



  4



  5



  6



  7



  8



9

Note:

1.  The number of nodes in the given tree will be between 1 and 100.
2. Each node will have a unique integer value from 0 to 1000. <br>
这道题给了一棵二叉树,让我们对其进行重排序,使得最左结点变为根结点,而且整个树不能有左子结点,如题目中的例子所示,排序后的结果是一条向右下方延伸的直线。如果我们仔细观察题目中的例子,可以发现遍历顺序其实是 左->根->右,就是中序遍历的顺序,虽然题目中没说是二叉搜索树,但这并不影响我们进行中序遍历。我们先从最简单的例子开始分析,当 root 为空时,直接返回空,当 root 没有左右子结点时,也是直接返回 root。当 root 只有一个左子结点时,我们此时要把其左子结点变为根结点,将原来的根结点变成其原来的左子结点的右子结点。但是如果 root 只有一个右子结点,还是保持原来的顺序不变,而若 root 同时具有左右子结点的话,还是要将左子结点变为根结点,然后把之前的根结点连到右子结点上,之前的右子结点还连在之前的根结点上,这个不用改变。我们可以发现,最麻烦的就是左子结点了,需要和其根结点交换位置,所以对于每个结点,我们需要知道其父结点的位置,那么就在递归函数的参数中传入一个 pre 结点,再对左右子结点调用递归函数时,都将其下一个要连接的结点传入,这个 pre 结点可能是当前结点或者当前结点的父结点。 在递归函数中,首先判空,若当前结点为空的话,直接返回 pre 结点,因为到空结点的时候,说明已经遍历到叶结点的下方了,那么 pre 就是这个叶结点了。由于是中序遍历,所以要先对左子结点调用递归函数,将返回值保存到一个新的结点 res 中,表示的意义是此时 node 的左子树已经全部捋直了,而且根结点就是 res,而且 node 结点本身也被连到了捋直后的左子树下,即此时左子结点和根结点已经完成了交换位子,当然要断开原来的连接,所以将 node->left 赋值为 nullptr。然后再对 node 的右子结点调用递归函数,注意此时的 pre 不能传入 node 本身,而是要传 node 结点的 pre 结点,这是因为右子结点后面要连接的是 node 的父结点,比如兑入下面这例子:
4

/

2

/

1 3


当运行到结点3的时候,pre 应该带入的是结点4,这样就可以把结点4连到结点3的右下方,从而正确的捋直,参见代码如下: <br>
解法一:

class Solution {

public:

TreeNode* increasingBST(TreeNode* root) {

return helper(root, nullptr);

}

TreeNode* helper(TreeNode* node, TreeNode* pre) {

if (!node) return pre;

TreeNode* res = helper(node->left, node);

node->left = nullptr;

node->right = helper(node->right, pre);

return res;

}

};



<br>
我们也可以采用中序遍历的迭代形式,使用栈来辅助。由于根结点可能会产生变化,所以我们需要一个 dummy 结点,还需要一个 pre 结点。在 while 循环中,先找到最左结点,把路径上的所有结点都压入栈,然后取出栈顶元素,将其连到 pre 的右子结点上,并将 pre 更新为其右子结点,然后断开栈顶元素的左子结点连接,并将其移动到右子结点上,并继续循环,最终返回 dummy 的右子结点即可,参见代码如下: <br>
解法二:

class Solution {

public:

TreeNode* increasingBST(TreeNode* root) {

TreeNode *dummy = new TreeNode(-1), pre = dummy;

stack<TreeNode
> st;

while (root || !st.empty()) {

while (root) {

st.push(root);

root = root->left;

}

root = st.top(); st.pop();

pre->right = root;

pre = pre->right;

root->left = nullptr;

root = root->right;

}

return dummy->right;

}

};


<br>
Github 同步地址: <https://github.com/grandyang/leetcode/issues/897> <br>
参考资料: <https://leetcode.com/problems/increasing-order-search-tree/> <https://leetcode.com/problems/increasing-order-search-tree/discuss/251290/C%2B%2B-short-iterative> <https://leetcode.com/problems/increasing-order-search-tree/discuss/165885/C%2B%2BJavaPython-Self-Explained-5-line-O(N)> <br>
[LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)

[LeetCode] 897. Increasing Order Search Tree 递增顺序查找树的更多相关文章

  1. LeetCode 897 Increasing Order Search Tree 解题报告

    题目要求 Given a tree, rearrange the tree in in-order so that the leftmost node in the tree is now the r ...

  2. 【Leetcode_easy】897. Increasing Order Search Tree

    problem 897. Increasing Order Search Tree 参考 1. Leetcode_easy_897. Increasing Order Search Tree; 完

  3. 897. Increasing Order Search Tree

    题目来源: https://leetcode.com/problems/increasing-order-search-tree/ 自我感觉难度/真实难度:medium/easy 题意: 分析: 自己 ...

  4. 【LeetCode】897. Increasing Order Search Tree 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 重建二叉树 数组保存节点 中序遍历时修改指针 参考资 ...

  5. [LeetCode&Python] Problem 897. Increasing Order Search Tree

    Given a tree, rearrange the tree in in-order so that the leftmost node in the tree is now the root o ...

  6. 【leetcode】897. Increasing Order Search Tree

    题目如下: 解题思路:我的方法是先用递归的方法找出最左边的节点,接下来再对树做一次递归中序遍历,找到最左边节点后将其设为root,其余节点依次插入即可. 代码如下: # Definition for ...

  7. LeetCode 897. 递增顺序查找树(Increasing Order Search Tree)

    897. 递增顺序查找树 897. Increasing Order Search Tree 题目描述 给定一个树,按中序遍历重新排列树,使树中最左边的结点现在是树的根,并且每个结点没有左子结点,只有 ...

  8. PAT Advanced 1064 Complete Binary Search Tree (30) [⼆叉查找树BST]

    题目 A Binary Search Tree (BST) is recursively defined as a binary tree which has the following proper ...

  9. PAT Advanced 1099 Build A Binary Search Tree (30) [⼆叉查找树BST]

    题目 A Binary Search Tree (BST) is recursively defined as a binary tree which has the following proper ...

随机推荐

  1. 【转】在cmd/bat脚本中获取当前脚本文件所在目录

    一.关于cd的/d参数 关于cd 的/d参数,在cmd中敲入cd /?可以看到/d参数的解释如下: 使用 /D 命令行开关,除了改变驱动器的当前目录之外,还可改变当前驱动器.这句话不太好理解,我做个试 ...

  2. D3力布图绘制--基本方法

    本文主要结合案例记录使用D3.js绘制力布图的基本方法 样例显示 基本配置 this.force = d3.layout .force() .size([this.width, this.height ...

  3. 【shell脚本】通过位置变量创建Linux账户及密码===addUser.sh

    通过位置变量创建Linux账户及密码 脚本内容 [root@VM_0_10_centos shellScript]# vi addUser.sh #!/bin/bash # 通过位置变量创建系统账户及 ...

  4. 连接树莓派中的MySQL服务器

    今天用笔记本连接树莓派的 MySQL ,结果连接不上.就直接连接到树莓派上进行操作.其实以前也知道远程访问 MySQL 需要进行配置,可以直接 mysql.user 表,也可以直接使用授权的 SQL ...

  5. jQuery 源码分析(一) 代码结构

    jQuery是一个Javascript库,它支持链式操作方式,即对发生在同一个JQuery对象上的一组动作,可以直接接连写无需要重复获取对象.这一特点使得JQuery的代码无比优雅,而且有强大的选择器 ...

  6. Socket与WebSocket以及http与https重新总结

    Socket与WebSocket以及http与https重新总结 一.Socket 网络中的Socket是一个抽象的接口 ,而是为了方便使用TCP或UDP而抽象出来的一层 ,可以理解为网络中连接的两端 ...

  7. Linux入门——初识Linux

    Linux入门——初识Linux 摘要:本文主要说明了Linux是什么,Linux发展历史,以及同Linux系统有关的一些基本知识. 简介 操作系统 Linux系统同Windows系统.Mac系统一样 ...

  8. Python【day 10】函数进阶-动态函数

    形参小结 1.位置参数2.默认值参数3.动态参数 1.*args 位置参数的动态传参. 系统会自动的把所有的位置参数聚合成元组 2.**kwargs 关键字参数的动态传参. 系统会自动的把所有的关键字 ...

  9. JZOJ 2158. 蚂蚁

    这个是今天早上比赛的内容,比较水给大伙们讲一下(我只会这一个) 题目大意: n只蚂蚁以每秒1cm的速度在长为L  cm(厘米,不是lcm)的竿子上爬行.当蚂蚁爬到竿子的端点时就会掉落.由于竿子太细,两 ...

  10. mysql数据库被攻击

    好久没有登录我自己的服务器了,今日登录发现mysql数据库沦陷了.我的数据库名字叫linkorganizer,是一个链接管理数据库.旧表已经丢失了,整个数据库只剩下一个warning表,它是黑客留下的 ...