题目链接
暴力思路
先对树进行前序遍历获得数组,然后从头到尾遍历数组构造列表
class Solution {
public void flatten(TreeNode root) {
//前序遍历
TreeNode head = new TreeNode();
head = root ;
Deque<TreeNode> sta = new LinkedList<TreeNode>();
List<Integer> arr = new ArrayList<Integer>();
while(!sta.isEmpty() || root != null){//前序遍历
while(root != null){
sta.push(root);
arr.add(root.val);//先放根节点
root = root.left;//遍历左子树
}
root = sta.pop();//这个root是放进数组后才压入栈的,所以无需操作
root = root.right;//遍历右子树(只要这个右节点不为空,下一个循环就会放入arr中)
}
int len = arr.size(), i = 1;
root = head;
while(i < len ){
TreeNode right = new TreeNode(arr.get(i));//构造右节点
head.right = right;
head.left = null;//左节点
head = head.right;
i++;
}
}
}
O(1)思路
自己写不来看题解的。
思路比较重要,思路懂了基本没问题。
public void flatten(TreeNode root) {
//总结,
//如果有左子树和右子树,移动在自己的左子树(next)的最右叶子节点(pre)
//将自己左子树变成右子树,左子树设为空
//自己变成右子树,重复步骤
//
//如果只有左子树直接将左子树移动到右子树
//
//只有右子树直接下移
TreeNode pre, next;
TreeNode cur = root;
while(cur != null){
if(cur.left != null){
next = cur.left;
pre = next;
while(pre.right != null){
pre = pre.right;
}
pre.right = cur.right;
cur.left = null;
cur.right = next;
}
cur = cur.right;
}
}