问题描述:
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
源码:
本来自己写了一个,也能得到结果,但是就是不对,可能因为赋值的原因,地址变了,所以只能在原有的上面动。为了纪念以下,也展示一下吧,这个代码跑不通,大家别直接复制。
/**
* 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* help(TreeNode* root){
if(!root->left && !root->right) return new TreeNode(root->val);
TreeNode *cur = new TreeNode(root->val), *tmp_cur = cur;
tmp_cur->left = NULL;
if(root->left) tmp_cur->right = help(root->left);
while(tmp_cur->right) tmp_cur = tmp_cur->right;
if(root->right) tmp_cur->right = help(root->right);
return cur;
}
void flatten(TreeNode* root) {
if(!root) return;
TreeNode* res = help(root);
root = res;
TreeNode *tmp = root;
while(tmp){
cout<<tmp->val<<" ";
tmp = tmp->right;
}
}
};
这样递归就很复杂,需要一个前置指针pre,而且每次都要保存右子树指针tmp,因为经过help(cur->left, cur)不知道cur指针跑哪去了。时间97%,空间100%。
class Solution {
public:
void help(TreeNode* cur, TreeNode* pre){
pre->right = cur;
if(!cur) return;
TreeNode *tmp = cur->right;
pre->left = NULL;
help(cur->left, cur);
while(pre->right) pre = pre->right;
help(tmp, pre);
}
void flatten(TreeNode* root) {
if(!root) return;
help(root, new TreeNode(0));
}
};
上面那种方法非递归要两个队列或者栈,有点划不来,就看了discuss另一个方法的非递归。
记录一个节点cur,起始为根节点。对于这个cur节点,如果有左子树,做两件事:
1. 把左子树的最右节点的right指针指向cur的右子树。
2. cur的right指针指向cur的左子树,cur的left指针指向null.
class Solution {
public:
void flatten(TreeNode* root) {
if(!root) return;
TreeNode *leftright, *cur=root;
while(cur){
if(cur->left){
leftright = cur->left;
while(leftright->right) leftright = leftright->right;
leftright->right = cur->right;
cur->right = cur->left;
cur->left = NULL;
}
cur = cur->right;
}
}
};
还有就是先序遍历法,很简单了,递归和非递归的方法如下。
// 递归
class Solution {
public:
TreeNode* cur = new TreeNode(-1);
void flatten(TreeNode* root) {
if(!root) return;
TreeNode *L = root->left, *R = root->right;
cur->right = root;
root->left = NULL;
root->right = NULL;
cur = cur->right;
flatten(L);
flatten(R);
}
};
// 非递归
class Solution {
public:
void flatten(TreeNode* root) {
if(!root) return;
stack<TreeNode*> st;
st.push(root);
while(!st.empty()){
TreeNode *tmp = st.top();
st.pop();
if(tmp->right) st.push(tmp->right);
if(tmp->left) st.push(tmp->left);
tmp->left = NULL;
if(!st.empty()) tmp->right = st.top();
else tmp->right = NULL;
}
}
};