通过递归实现前序遍历
递归就是嵌套调用同一个方法,只是参数范围在不断变化(说得怎么有点儿怪怪的)
前序遍历,先把根节点放入list中,递归左孩子,完后,再递归右孩子
依次把节点都放入list后
list转为treenode形式的链表(其中 right 子指针指向链表中下一个结点,而左子指针始终为 null)
class Solution {
public void flatten(TreeNode root) {
List<TreeNode> list = new ArrayList<TreeNode>();
preorderTraversal(root, list);
int size = list.size();
for (int i = 1; i < size; i++) {
TreeNode prev = list.get(i - 1), curr = list.get(i);
prev.left = null;
prev.right = curr;
}
}
public void preorderTraversal(TreeNode root, List<TreeNode> list) {
if (root != null) {
list.add(root);
preorderTraversal(root.left, list);
preorderTraversal(root.right, list);
}
}
or 通过迭代实现前序遍历
待展开的二叉树Root:node
前序遍历,把根节点不断放入stack后,获取左孩子,判断左孩子是否存在
左孩子不存在后,弹出stack中节点,并获取其右孩子
list是前序遍历列表
转list为链表(treenode形式的链表)
class Solution {
public void flatten(TreeNode root) {
List<TreeNode> list = new ArrayList<TreeNode>();
Deque<TreeNode> stack = new LinkedList<TreeNode>();
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;
}
int size = list.size();
for (int i = 1; i < size; i++) {
TreeNode prev = list.get(i - 1), curr = list.get(i);
prev.left = null;
prev.right = curr;
}
}
}
看懂了,写不写出来不一定
空间复杂度降为1,这个有意思
根节点(current节点)的左节点存在,寻找这个左节点的最右子节点,为根节点的右孩子的前驱节点
左节点的最右子节点的右节点设置为current节点的右孩子
当前节点的左孩子设为null,右孩子节点为current节点的左孩子
当前节点的右孩子是下一个current节点
class Solution {
public void flatten(TreeNode root) {
TreeNode curr = root;
while (curr != null) {
if (curr.left != null) {
TreeNode next = curr.left;
TreeNode predecessor = next;
while (predecessor.right != null) {
predecessor = predecessor.right;
}
predecessor.right = curr.right;
curr.left = null;
curr.right = next;
}
curr = curr.right;
}
}
}