解题思路
两种思路:
第一种,我们考虑什么情况下能实现题目的要求呢?其实很简单,只要分成两步,第一步,把当前节点的左孩子放在右孩子的位置;第二步,把右孩子放在左孩子的最右节点的右孩子上面。这两步哪一步在前都可以。然后再对当前结点的右孩子重复执行上面这个步骤就可以了。
第二种思路,在原来的树上进行修改。题目要的是一个前序遍历的顺序,那么我们就按照前序,遍历到一个节点,就把它的前一个结点的右节点指向它,这样可以吗?是不可以的,因为按照前序遍历的顺序,修改了前一个结点的右孩子之后,前一个结点原来的右孩子就丢失了。所以我们按照右左根这样的后序遍历顺序来遍历,每遍历到一个结点,就让这个结点的右孩子指向前一个结点,这样就可以了。
代码
//第一种方法的递归版本
class Solution {
public void flatten(TreeNode root) {
traversal(root);
}
public void traversal(TreeNode root){
if (root==null) return;
TreeNode right=root.right;
root.right=root.left;
root.left=null;
TreeNode t=root;
while (t.right!=null) t=t.right;
t.right=right;
traversal(root.right);
}
}
//第一种方法的迭代版本
class Solution {
public void flatten(TreeNode root) {
if (root==null) return;
while (root!=null){
TreeNode right=root.right;
root.right=root.left;
root.left=null;
TreeNode t=root;
while (t.right!=null) t=t.right;
t.right=right;
root=root.right;
}
}
}
//第二种
class Solution {
public void flatten(TreeNode root) {
traversal(root);
}
TreeNode pre=null;
public void traversal(TreeNode root){
if (root==null) return;
traversal(root.right);
traversal(root.left);
if (pre!=null){
root.right=pre;
root.left=null;
}
pre=root;
}
}