题目
Given a tree, rearrange the tree in in-order so that the leftmost node in the tree is now the root of the tree, and every node has no left child and only 1 right child.
大意
给出一个树,重新排列,使得最左的节点是树的根节点,并且每个节点只有一个右孩子而没有左孩子。
样例
Example 1: Input: [5,3,6,2,4,null,8,1,null,null,null,7,9] 5 / \ 3 6 / \ \ 2 4 8 / / \ 1 7 9 Output: [1,null,2,null,3,null,4,null,5,null,6,null,7,null,8,null,9] 1 \ 2 \ 3 \ 4 \ 5 \ 6 \ 7 \ 8 \ 9
思路
一、可以观察到,排列之后的树从左上到右下遍历刚好与排列之前的中序遍历得到的序列一模一样,所以中序遍历未排列的,用一个vector保存,再用这个vector构造树。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void inorder(TreeNode *root,vector<int> &result)
{
if(!root)return;
inorder(root->left,result);
result.push_back(root->val);
inorder(root->right,result);
}
TreeNode* increasingBST(TreeNode* root) {
vector<int>result;
inorder(root,result);
TreeNode *ans=new TreeNode(0);TreeNode *cur=ans;
for(int i=0;i<result.size();i++)
{
ans->right=new TreeNode(result[i]);
ans=ans->right;
}
return cur->right;
}
};
需要注意的是,inorder中序遍历函数中的vector参数需要为引用参数,并且,在重新排列的过程中,需要用cur保存第一次构建的树,然后像链表一样构造它的子树,如果不使用cur,最后得到的ans是叶节点而不是根。
二、leetcode的最优解,看的不太懂。。。。大致是把一个树调整一下,将左叶节点作为根节点,根节点作为左叶节点的右节点,右节点作为叶节点。递归调用
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode *curr;
void traversal(TreeNode *root) {
if(!root) return;
traversal(root->right);
root->right = curr;
curr = root;
traversal(root->left);
root->left = nullptr;
}
TreeNode* increasingBST(TreeNode* root) {
traversal(root);
return curr;
}
};