Given a binary tree, flatten it to a linked list in-place.
For example, given the following tree:
1
/ \
2 5
/ \ \
3 4 6
The flattened tree should look like:
1
\
2
\
3
\
4
\
5
\
6
自己的代码:
public static void flatten(TreeNode root) {
if(root == null) return;
flatten(root.left);
flatten(root.right);
TreeNode rightOfroot = root.right;
if(root.left != null)
root.right = root.left;
// 不能想当然认为上面有root.right = root.left,就写:cur = root.right
// 要防止,if(root.left != null)这个if判断进不来的情况
TreeNode cur = root.left;
root.left = null; // 这句不能少,一定要置null,否则测试用例通不过
while(cur != null && cur.right != null ) // cur.right之前要先进行cur的非空判断
cur = cur.right;
if(cur != null) // cur.right之前要先进行cur的非空判断
cur.right = rightOfroot;
}
核心思想:
先把左右子树各自使用递归函数变化成题目中要求的形式;
然后让根节点右指针指向变化后的左子树,最后让左子树的最右下方节点的右指针指向变化后的根节点的右子树
别人的代码:
思想与自己的一模一样,但代码更为简洁
public static void flatten1(TreeNode root) {
if (root == null) return;
TreeNode left = root.left;
TreeNode right = root.right;
root.left = null;
flatten1(left);
flatten1(right);
root.right = left;
TreeNode cur = root;
while (cur.right != null) cur = cur.right;
cur.right = right;
}
别人的代码:
class Solution {
public:
void flatten(TreeNode *root) {
TreeNode*now = root;
while (now)
{
if(now->left)
{
//Find current node's prenode that links to current node's right subtree
TreeNode* pre = now->left;
while(pre->right)
{
pre = pre->right;
}
pre->right = now->right;
//Use current node's left subtree to replace its right subtree(original right
//subtree is already linked by current node's prenode
now->right = now->left;
now->left = NULL;
}
now = now->right;
}
}
};
核心思想:
当前节点,若存在左子树,则找到当前节点的“前驱节点pre”,并让pre指向当前节点的右子树, 再当当前节点的右子树指向当前节点的左子树,最后将当前节点的左子树置为null
若不存在左子树,则直接让当前节点指向它的右子树,进入下一轮while循环
方法二
class Solution {
public:
void flatten(TreeNode* root) {
TreeNode* prev = NULL;
flatten(root, prev);
}
private:
void flatten(TreeNode* root, TreeNode*& prev) {
if (!root) {
return;
}
flatten(root -> right, prev);
flatten(root -> left, prev);
root -> right = prev;
root -> left = NULL;
prev = root;
}
};
核心思想:类似于后续遍历