携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第24天,点击查看活动详情
一、题目
LeetCode#### 展平二叉搜索树
给你一棵二叉搜索树,请 按中序遍历 将其重新排列为一棵递增顺序搜索树,使树中最左边的节点成为树的根节点,并且每个节点没有左子节点,只有一个右子节点。
示例 1:
输入:root = [5,3,6,2,4,null,8,1,null,null,null,7,9]
输出:[1,null,2,null,3,null,4,null,5,null,6,null,7,null,8,null,9]
示例 2:
输入:root = [5,1,7]
输出:[1,null,5,null,7]
提示:
树中节点数的取值范围是 [1, 100]
0 <= Node.val <= 1000
二、题解
按题目要求遍历构造新二叉树即可。
方法一
简单的根据题目意思执行就好了,首先对给定的二叉搜索树继续中序遍历,获得中序遍历的节点值集合。然后再根据中序遍历的结果来构造一个二叉树,二叉树中只包含有右子树右节点。具体的首先需要一个list集合存储中序遍历的节点值,然后使用dfs深度优先搜索来遍历二叉树节点,中序遍历先遍历左子树节点,然后再遍历根节点,最后再遍历右子树的节点。遍历完成之后需要根据结果list来构造新二叉树,先新建一个头结点head,然后用node指针指向头结点,最后直接按顺序遍历list结果集,新建节点存储当前遍历的值,将节点放置到node的右子树上,然后指针后移到右子树上,最后遍历完成就构造出一个新二叉树返回即可。
方法二 同样的可以直接在中序遍历的过程中继续新二叉树的构造,直接用在dfs深度优先搜索过程中获取的节点值来构造新节点,这样就不用先保持遍历结果,重新遍历构造了。
三、代码
方法一 Java代码
class Solution {
List<Integer> list = new ArrayList<Integer>();
public TreeNode increasingBST(TreeNode root) {
dfs(root);
TreeNode head = new TreeNode(0);
TreeNode node = head;
for (int val : list) {
node.right = new TreeNode(val);
node = node.right;
}
return head.right;
}
public void dfs(TreeNode root) {
if (root == null) {
return;
}
dfs(root.left);
list.add(root.val);
dfs(root.right);
}
}
时间复杂度:O(n),需要中序遍历一次二叉树节点。
空间复杂度:O(n),递归消耗栈空间和存储中序遍历节点值。
方法二 Java代码
class Solution {
TreeNode head = new TreeNode(0);
TreeNode node = head;
public TreeNode increasingBST(TreeNode root) {
dfs(root);
return head.right;
}
void dfs(TreeNode root) {
if (root == null) {
return;
}
dfs(root.left);
node.right = new TreeNode(root.val);
node = node.right;
dfs(root.right);
}
}
时间复杂度:O(n),需要中序遍历一次二叉树节点。
空间复杂度:O(n),递归消耗栈空间。