展平二叉搜索树

101 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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),递归消耗栈空间。