Leetcode114
1.问题描述
2.解决方案
解法一:前序遍历加递归建树
先序遍历没什么可说的,然后就是递归建树,递归中把这种边界条件一定要想清楚了,把过程找几个比较一般的例子和极端的例子分析了就很容易了,递归建立树就按递归的套路来就好,重要的边界条件。
if(q.size()==0) return;
if(root== nullptr) root=new TreeNode;
class Solution {
public:
queue<int> q;
void preInorder(TreeNode* root){
if(root== nullptr) return;
q.push(root->val);
preInorder(root->left);
preInorder(root->right);
}
void build(TreeNode*& root){
if(q.size()==0) return;
if(root== nullptr) root=new TreeNode;
root->val=q.front();
q.pop();
root->left= nullptr;
build(root->right);
}
void flatten(TreeNode* root) {
preInorder(root);
build(root);
}
};
解法二:前序遍历加迭代建树
这个优势在于把节点指针放入vector中,而且使用at函数而不是[]运算符,然后for循环设计的很巧妙,第一次取 0 1 第二次取 1 2 正好交替取节点,有个衔接正好 然后建树,迭代的技巧可取。
class Solution1 {
public:
void preorderTraversal(TreeNode* root, vector<TreeNode*> &l) {
if (root != NULL) {
l.push_back(root);
preorderTraversal(root->left, l);
preorderTraversal(root->right, l);
}
}
void flatten(TreeNode* root) {
vector<TreeNode*> l;
preorderTraversal(root, l);
//迭代建树
int n = l.size();
for (int i = 1; i < n; i++) {
//第一次取 0 1 第二次取 1 2 正好交替取节点,有个衔接正好 然后建树
TreeNode *prev = l.at(i - 1), *curr = l.at(i);
prev->left = nullptr;
prev->right = curr;
}
}
};
解法三:前序遍历和展开同步进行(还没看)
class Solution {
public:
void flatten(TreeNode* root) {
if (root == nullptr) {
return;
}
auto stk = stack<TreeNode*>();
stk.push(root);
TreeNode *prev = nullptr;
while (!stk.empty()) {
TreeNode *curr = stk.top(); stk.pop();
if (prev != nullptr) {
prev->left = nullptr;
prev->right = curr;
}
TreeNode *left = curr->left, *right = curr->right;
if (right != nullptr) {
stk.push(right);
}
if (left != nullptr) {
stk.push(left);
}
prev = curr;
}
}
};
解法四:寻找前驱节点(还没看看一下空间复杂度优秀)
class Solution {
public:
void flatten(TreeNode* root) {
TreeNode *curr = root;
while (curr != nullptr) {
if (curr->left != nullptr) {
auto next = curr->left;
auto predecessor = next;
while (predecessor->right != nullptr) {
predecessor = predecessor->right;
}
predecessor->right = curr->right;
curr->left = nullptr;
curr->right = next;
}
curr = curr->right;
}
}
};