著者:Steven Zhai
著作権表示:著作権は著者に帰属します。商用の再版については、承認を得るために著者に連絡してください。非商用の再版については、出典を示してください。
トピックの説明:
二分木のノードが与えられた場合、次のノードを逆順で見つけて戻ります。ツリー内のノードには、左右の子ノードだけでなく、親ノードへの次のポインタも含まれていることに注意してください。次の図は、9ノードの二分木を示しています。ツリー内の親ノードから子ノードへのポインターは実線で表され、子ノードから親ノードへのポインターは破線で表されます。
例:
入力:{8,6,10,5,7,9,11}、8
返品:9
分析:このアセンブリによって渡されるサブツリーのルートノードは、実際にはツリー全体です。順番にトラバーサル{5,6,7,8,9,10,11}、ルートノード8の次のノードは9です。これは{9,10,11}を返すはずですが、背景はサブツリーの次のノードのみを印刷するため、下の図に示すように9のみが印刷されます。実際、左右の子へのポインターもあります。下の図には描かれていない親ノードへのポインタとして
データ範囲:ノードの数は1≤n≤50を満たし、ノードの値は1≤val≤100の
要件を満たします:空間の複雑さO(1)、時間の複雑さO(n)
例:
入力:
{8,6,10,5,7,9,11}、8
戻り値:
9
問題解決のアイデア:
この質問では、データ構造ツリーの使用について調べます。2つの方法:
1)ブルートフォースクラッキング。次のポインタを介してルートノードを取得し、途中で並べ替え、並べ替えプロセス中にベクトルに格納してから、位置に従って直接出力します。
2)順序どおりの並べ替えのプロパティと組み合わせる。ノードに右のサブツリーがある場合、右のサブツリーの左端の子が次のノードになります。右のサブツリーがない場合、最初の右の親が次のノードになります。
テストコード:
1)ブルートフォースクラッキング。
/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
*/
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode) {
if(!pNode)
return NULL;
// 确定根结点
TreeLinkNode* root=pNode;
while(root->next)
{
root=root->next;
}
// 中序排序
vector<TreeLinkNode*> v;
inorder(root,v);
for(int i=0;i<v.size();++i)
{
if(v[i]==pNode&&(i+1)<v.size())
return v[i+1];
}
return NULL;
}
// 排序
void inorder(TreeLinkNode* root,vector<TreeLinkNode*> &v)
{
if(!root)
return;
// 中序排序
inorder(root->left,v);
v.push_back(root);
inorder(root->right,v);
}
};
2)順序どおりの並べ替えのプロパティと組み合わせる。
/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
*/
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode) {
if(!pNode)
return NULL;
// 判断是否存在右子树
if(pNode->right)
{
TreeLinkNode* target=pNode->right;
// 取最左孩子
while(target->left)
{
target=target->left;
}
return target;
}
// 不存在右子树,寻找第一个右父亲
while(pNode->next)
{
if(pNode->next->left==pNode)
return pNode->next;
pNode=pNode->next;
}
return NULL;
}
};