题目
给定一个二叉树,原地将它展开为一个单链表。
方法一:前序遍历
递归前序遍历记录节点,然后重新展成单链表。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public void flatten(TreeNode root) {
List<TreeNode> listnode=new ArrayList<>();
preOrder(root,listnode);
int size=listnode.size();
for(int i=1;i<listnode.size();i++){
TreeNode pre=listnode.get(i-1),now=listnode.get(i);
pre.left=null;
pre.right=now;
}
}
void preOrder(TreeNode root,List<TreeNode> listnode){
if(root==null){
return;
}
listnode.add(root);
preOrder(root.left,listnode);
preOrder(root.right,listnode);
}
}
迭代前序遍历节点。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
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 pre=list.get(i-1),curr=list.get(i);
pre.left=null;
pre.right=curr;
}
}
}
方法二:前序遍历和展开同步进行
使用栈遍历,可以有左右子树的先后痕迹,因此可以直接在遍历中同步链接。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public void flatten(TreeNode root) {
if(root==null) return;
Deque<TreeNode> stack=new LinkedList<TreeNode>();
stack.push(root);
TreeNode pre=null;
while(!stack.isEmpty()){
TreeNode cur=stack.pop();
if(pre!=null){
pre.left=null;pre.right=cur;
}
if(cur.right!=null){
stack.push(cur.right);
}
if(cur.left!=null){
stack.push(cur.left);
}
pre=cur;
}
}
}
方法三:寻找前驱节点
题目中要求原地展开,感觉主要是要这个方法:即不通过栈,而是O(1)的空间复杂度来完成。
这也是最快的方法。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public void flatten(TreeNode root) {
TreeNode cur=root;
while(cur!=null){
if(cur.left!=null){
TreeNode next=cur.left;
TreeNode pre=next;
while(pre.right!=null){
pre=pre.right;
}
pre.right=cur.right;
cur.left=null;
cur.right=next;
}
cur=cur.right;
}
}
}