【Leetcode】114. 二叉树展开为链表

104 阅读1分钟

题目描述

在这里插入图片描述

// 114. 二叉树展开为链表

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

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

// 提示:

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

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

题解

// 这题如果直接前序遍历构建链表那也太简单了,毫无意义昂。
// 直接看最优解,原地O(1)空间的展开。
// 
// 如果root不为空,执行while循环,循环中,如果root左子节点root.left为空,
// 则root指针移动到root链表的下一个结点,也就是root = root.right,继续判断
// 是否存在左子节点。
// 如果存在左子结点,那我们合并的目标就找到了,标记左子结点(或左子树根节点)
// 为leftRight,之后while循环一直移动leftRight到leftRight.right,找到左子树
// 的最右结点。将根节点的右子树并到leftRight的right(将链表合并到左子树最右
// 结点之后),再将整棵左树归位到root.right中(并到链表中),这样root.left
// 就空了,原来root.left被我们并到root.right中了。为了符合规范,将root.left
// 置null。
// 之后root移动到链表的下一个结点root.right,继续刚刚的判断和合并操作。
// 直到链表中的所有结点都做一次判断和合并。链表就构成了。
// 
class Solution {
	public void flatten(TreeNode root) {
		while (root != null) {
			if (root.left != null) {
				TreeNode leftRight = root.left;
				while (leftRight.right != null)
					leftRight = leftRight.right;
				leftRight.right = root.right;
				root.right = root.left;
				root.left = null;
			}
			root = root.right;
		}
    }
}