给定一个二叉树,原地将它展开为一个单链表。
例如,给定二叉树
1
/ \
2 5
/ \ \
3 4 6
将其展开为:
1
\
2
\
3
\
4
\
5
\
6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
感谢 林小鹿 大佬的详细解法,传送门 二叉树展开为链表 | 图解树的遍历 | 代码简洁易懂 【C++/Java版本】
class Solution {
public void flatten(TreeNode root) {
// flattenI(root);
// flattenII(root);
//方法三:迭代
//时间复杂度O(N),空间复杂度O(1)
if (root == null) {
return;
}
TreeNode cur = root;
while (cur != null) {
//右子树不需要展开,展开左子树
TreeNode node = cur.left;
if (node != null) {
//找到左子树的最右节点
while (node.right != null) {
node = node.right;
}
//将原来的右子树接到左子树的最右边节点
node.right = cur.right;
//将左边的树放到右边
cur.right = cur.left;
//左边置为null
cur.left = null;
}
cur = cur.right;
}
}
//方法二:前序遍历,遍历过程中修改节点的右指针方向
//时间复杂度O(N),空间复杂度O(N)
private void flattenII(TreeNode root) {
if (root == null) {
return;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
TreeNode prev = null;
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
//每遍历一个节点就将上一节点的右指针指向当前节点
if (prev != null) {
prev.right = node;
prev.left = null;
}
if (node.right != null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
prev = node;
}
}
//方法一:递归
//时间复杂度O(N),空间复杂度O(N)
private void flattenI(TreeNode root) {
if (root == null) {
return;
}
//理解递归函数的含义:将二叉树展开为单链表
//分别展开左子树和右子树
flatten(root.left);
flatten(root.right);
//展开为链表的右子树
TreeNode temp = root.right;
//将树的左边放到右边
root.right = root.left;
//左边置为null
root.left = null;
while (root.right != null) {
root = root.right;
}
//将右子树的链表放到左子树链表的最右边
root.right = temp;
}
}