Skip to content

Latest commit

 

History

History
96 lines (76 loc) · 3.04 KB

递归.md

File metadata and controls

96 lines (76 loc) · 3.04 KB

递归的特点!!仔细体悟:不用想函数的内部细节是如何处理的,我们只看其函数作用,输入与返回值。

Difficulty: 中等

给你二叉树的根结点 root ,请你将它展开为一个单链表:

  • 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null
  • 展开后的单链表应该与二叉树 顺序相同。

示例 1:

输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [0]
输出:[0]

提示:

  • 树中结点数在范围 [0, 2000]
  • -100 <= Node.val <= 100

**进阶:**你可以使用原地算法(O(1) 额外空间)展开这棵树吗?

思路1:递归。 递归的特点:不用想函数的内部细节是如何处理的,我们只看其函数作用,输入与返回值。 首先将根节点的左子树变成链表。 其次将根节点的右子树变成链表。 最后将变成链表的右子树放在变成链表的左子树的最右边。

思路2:迭代。O(1)解法。要把左边的节点放到右边,右边的节点该放在哪里呢?放在左边节点的最右侧的节点的右边,放好以后,继续往下即可。

    //思路1:递归
	public void flatten(TreeNode root) {
        if(root == null){
            return ;
        }
        //将根节点的左子树变成链表
        flatten(root.left);
        //将根节点的右子树变成链表
        flatten(root.right);
        TreeNode temp = root.right;
        //把树的右边换成左边的链表
        root.right = root.left;
        //记得要将左边置空
        root.left = null;
        //找到树的最右边的节点
        while(root.right != null) {
            root = root.right;
        }
        //把右边的链表接到刚才树的最右边的节点
        root.right = temp;
    }

	//思路2: 迭代
	 public void flatten(TreeNode root) {
        while (root != null) { 
            //左子树为 null,直接考虑下一个节点
            if (root.left == null) {
                root = root.right;
            } else {
                // 找左子树最右边的节点
                TreeNode pre = root.left;
                while (pre.right != null) {
                    pre = pre.right;
                } 
                //将原来的右子树接到左子树的最右边节点
                pre.right = root.right;
                // 将左子树插入到右子树的地方
                root.right = root.left;
                root.left = null;
                // 考虑下一个节点
                root = root.right;
            }
        }
    }