题目
给你二叉树的根结点 root ,请你将它展开为一个单链表:
- 展开后的单链表应该同样使用
TreeNode,其中right子指针指向链表中下一个结点,而左子指针始终为null。 - 展开后的单链表应该与二叉树 先序遍历 顺序相同。
示例 1:
输入: root = [1,2,5,3,4,null,6]
输出: [1,null,2,null,3,null,4,null,5,null,6]
题解
方式一:前序遍历(递归)
Deque<TreeNode> deque = new LinkedList<>();
public void flatten(TreeNode root) {
TreeNode cur = root;
preOrder(root);
deque.pollFirst();
// 重新构建二叉树
while (!deque.isEmpty()) {
cur.right = deque.pollFirst();
cur = cur.right;
}
}
public void preOrder(TreeNode node) {
if (node == null) {
return;
}
deque.offerLast(node);
// 断开原来的节点
if (node.left != null) {
preOrder(node.left);
node.left = null;
}
if (node.right != null) {
preOrder(node.right);
node.right = null;
}
}
方式二:前序遍历(迭代)
public void flatten(TreeNode root) {
List<TreeNode> list = new ArrayList<>(); // 本题需要记录全序遍历节点
Stack<TreeNode> stack = new Stack<>();
TreeNode node = root;
while (node != null || !stack.isEmpty()) {
while (node != null) {
list.add(node);
stack.push(node);
node = node.left;
}
node = stack.pop();
node = node.right;
}
for (int i = 1; i < list.size(); i++) { // 展开
TreeNode pre = list.get(i - 1);
TreeNode cur = list.get(i);
pre.left = null;
pre.right = cur;
}
}
方式三:前序遍历
public void flatten(TreeNode root) {
if(root == null) {
return;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
TreeNode pre = null;
while (!stack.isEmpty()) {
TreeNode cur = stack.pop();
if (pre != null) {
pre.left = null;
pre.right = cur;
}
TreeNode left = cur.left, right = cur.right;
if (right != null) {
stack.push(right);
}
if (left != null) {
stack.push(left);
}
pre = cur;
}
}
方式四:递归
public void flatten(TreeNode root) {
if(root == null) {
return;
}
flatten(root.left);
flatten(root.right);
TreeNode tem = root.right;
root.right = root.left;
root.left = null;
while (root.right != null) {
root = root.right;
}
root.right = tem;
}
总结
算法:递归、前序遍历