给定一个树,按中序遍历重新排列树,使树中最左边的结点现在是树的根,并且每个结点没有左子结点,只有一个右子结点。
示例 :
输入:[5,3,6,2,4,null,8,1,null,null,null,7,9]
5
/ \
3 6
/ \ \
2 4 8
/ / \
1 7 9
输出:[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
提示:
给定树中的结点数介于 1 和 100 之间。
每个结点都有一个从 0 到 1000 范围内的唯一整数值。
【题解】:
本题就是用到二叉排序树的性质。对于任意一个节点,如果它存在左孩子,那么左孩子的值一定小于该节点的值;若它存在右孩子,则右孩子的值一定大于该节点的值。
还需要注意的是,如果对二叉排序树(BST)进行一次中序遍历,那么我们就可以得到一个有序的序列了。
因此,本题思路,先对二叉排序树进行一次中序遍历,将遍历结果存到一个List中。然后再逐一从list中取出节点重新建树即可。
值得注意的是,我在提交的时候多次出现 超出内存限制 的提示,这是因为我在建树的时候没有将节点的left置为null。因为TreeNode在java中都是引用类型,如果不改left指针的值,那么会引起问题。然后最后一个节点我们也要将它的left和right都置为null。这样才能得到正确的结果。
AC代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
List<TreeNode> list;
//存放最后结果树的根节点
TreeNode resRoot;
/**
中序遍历
**/
public void midOrder(TreeNode node){
if(node == null){
return ;
}
midOrder(node.left);
list.add(node);
midOrder(node.right);
}
public TreeNode increasingBST(TreeNode root) {
list = new ArrayList<TreeNode>();
midOrder(root);
//得到第一个节点
TreeNode preNode = list.get(0);
preNode.left = null;
resRoot = preNode;
TreeNode curNode = preNode;
for(int i = 1;i < list.size();i++){
curNode = list.get(i);
//每个节点的left都要置null
curNode.left = null;
preNode.right = curNode;
preNode = curNode;
}
//最后一个节点的right也要为null
preNode.right = null;
return resRoot;
}
}