[C++]LeetCode:102 Flatten Binary Tree to Linked List(ツリー回転前シーケンスチェーンテーブル)
3976 ワード
タイトル:
Given a binary tree, flatten it to a linked list in-place.
For example, Given
The flattened tree should look like:
click to show hints.
Hints:
If you notice carefully in the flattened tree, each node's right child points to the next node of a pre-order traversal.
Answer 1:再帰法
考え方:テーマ変換の過程を観察して、私たちは前の順序でチェーンテーブルに接続しましたが、チェーンテーブルは木の構造で、ずっと右へ(子供をしていません)チェーンテーブルをシミュレートします.ノード間のリンクを保証するために、最初にループした前のノードpreを維持し、preの左ノードを空にするたびに、右ノードを現在のノード(すなわち、順にループする順序)に設定します.ここでは、右の子供ノードsavedRightをメンテナンスして、再帰を容易にする必要があります.そうでないと、現在のノードの右ノードが上書きされ、後ろに取り出せない可能性があります.
ツリーの再帰方法は,主に再帰終了条件と再帰条件を考慮し,再帰がツリーの構造を修正する場合は,ノードを保存する必要がある.
Attention:
1.前のノードpre、現在のノードの右の子ノードsavedRightの順に2つのノードを維持します.右の子供ノードのリンクと保護を容易にします.
3.root->left再帰、次にメンテナンスの右ノード再帰savedRightの順に注意してください.preは常に維持されます.
AC Code:
Answer 2:非再帰法
考え方:
[問題を解く考え方]
rootの左サブツリーを処理し、左サブツリーのルートノードと左サブツリーの右サブツリーを右サブツリーに挿入します.次にノード2を処理し,同様に2の左サブツリーを右サブツリーに挿入する.ノード2(ルートノードの左子)の最右ノード(左サブツリーの最上位層の最右ノード,最後にアクセス)にアクセスすることにより,左サブツリーの最後のノード(ノード4)を順に遍歴し,ルートノードに挿入された右サブ(ノード5)の前のノード(ノード4)を得た.この挿入プロセスを継続します.
Attention:
1.右の子の木の前のノードを見つけると、根のノードの左の子の最も右のノードになります.
AC Code:
Given a binary tree, flatten it to a linked list in-place.
For example, Given
1
/ \
2 5
/ \ \
3 4 6
The flattened tree should look like:
1
\
2
\
3
\
4
\
5
\
6
click to show hints.
Hints:
If you notice carefully in the flattened tree, each node's right child points to the next node of a pre-order traversal.
Answer 1:再帰法
考え方:テーマ変換の過程を観察して、私たちは前の順序でチェーンテーブルに接続しましたが、チェーンテーブルは木の構造で、ずっと右へ(子供をしていません)チェーンテーブルをシミュレートします.ノード間のリンクを保証するために、最初にループした前のノードpreを維持し、preの左ノードを空にするたびに、右ノードを現在のノード(すなわち、順にループする順序)に設定します.ここでは、右の子供ノードsavedRightをメンテナンスして、再帰を容易にする必要があります.そうでないと、現在のノードの右ノードが上書きされ、後ろに取り出せない可能性があります.
ツリーの再帰方法は,主に再帰終了条件と再帰条件を考慮し,再帰がツリーの構造を修正する場合は,ノードを保存する必要がある.
Attention:
1.前のノードpre、現在のノードの右の子ノードsavedRightの順に2つのノードを維持します.右の子供ノードのリンクと保護を容易にします.
private:
TreeNode* pre = NULL; // , pre
TreeNode* savedRight = root->right;
2. リンクプロセスに注意して、私たちはpreの左の子供を空にして、右の子供を現在のノードにして、前の順序のチェーンテーブルのリンクを実現します.if(pre != NULL)
{
pre->left = NULL; //
pre->right = root; // root
}
3.root->left再帰、次にメンテナンスの右ノード再帰savedRightの順に注意してください.preは常に維持されます.
pre = root;
flatten(root->left);
flatten(savedRight); // ,
複雑度:O(N)AC Code:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void flatten(TreeNode *root) {
if(root == NULL) return;
TreeNode* savedRight = root->right;
if(pre != NULL)
{
pre->left = NULL; //
pre->right = root; // root
}
pre = root;
flatten(root->left);
flatten(savedRight); // ,
}
private:
TreeNode* pre = NULL; // , pre
};
Answer 2:非再帰法
考え方:
[問題を解く考え方]
1
\
2
/ \
3 4
\
5
\
6
rootの左サブツリーを処理し、左サブツリーのルートノードと左サブツリーの右サブツリーを右サブツリーに挿入します.次にノード2を処理し,同様に2の左サブツリーを右サブツリーに挿入する.ノード2(ルートノードの左子)の最右ノード(左サブツリーの最上位層の最右ノード,最後にアクセス)にアクセスすることにより,左サブツリーの最後のノード(ノード4)を順に遍歴し,ルートノードに挿入された右サブ(ノード5)の前のノード(ノード4)を得た.この挿入プロセスを継続します.
Attention:
1.右の子の木の前のノードを見つけると、根のノードの左の子の最も右のノードになります.
TreeNode* ptr = root->left;
while(ptr->right) ptr = ptr->right;
2. 挿入方法に注意してください.結合図記憶ptr->right = root->right;
root->right = root->left;
root->left = NULL;
3. rootをrootに設定した右の子供は、rootがNULLであることを知っています.つまり、rootがツリーの最後のノードに遍歴していることを知っています.AC Code:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void flatten(TreeNode *root) {
while(root)
{
if(root->left)
{
TreeNode* ptr = root->left;
while(ptr->right) ptr = ptr->right;
ptr->right = root->right;
root->right = root->left;
root->left = NULL;
}
root = root->right;
}
}
};