注文バイナリ検索ツリーの後継者は:BSTから指定されたノードの次のノードを検索します。
次の例は、次のいずれかが、2,2-、3,4- 5です。
思考:
方法1:再帰的トラバーサル順序は次のPを得るために、リストを取得し、実行します。時間O(N)、スペースO(N)
方法2:
再帰トラバーサルシーケンス実行は、再帰的なプロセスにおいて、xの次をフェッチします。電流値が<= X、のみBSTの特性に応じて右サブツリーを見つける必要があります。現在の値が> X、現在の値が可能である場合は、その左部分木はおそらく、小さいが> X、及び左側のサブ再帰を持つように近い(小さい)。に選んでもあり
時間O(logN個)スペースO(logN個)コールスタックの深さ。
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
if(p==null||root==null){
return null;
}
if(root.val<=p.val){//当前和左边都不可能>p
return inorderSuccessor(root.right,p);
}
//root>p
TreeNode res1=inorderSuccessor(root.left,p);
if(res1!=null&&res1.val<root.val){
return res1;
}else{
return root;
}
}
方法3:達成環状
CUR = cur.right:現在の値が<= Xである場合には、その後だけ右サブツリー内のBSTの特性を見つける必要があります。
現在の値が> X、現在の値が可能であるならば、左のサブツリーが小さいが> Xのを持っているということも可能です。このブランチにたびに、現在の点が候補点であり、ノードの最小値は、ノードの履歴を記録します。
時間O(logN個)、スペースO(1)
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
if(p==null||root==null){
return null;
}
TreeNode cur=root;
TreeNode res=null;
while(cur!=null){
if(cur.val<=p.val){
cur=cur.right;
}else{
if(res==null||res.val>cur.val){
res=cur;
}
cur=cur.left;
}
}
return res;
}
その後のシーケンスIIでバイナリ検索ツリーは、上記、及びこの質問の問題は、唯一の違いは、バイナリノードは通常ノード、さらにポインタを有する親ノードではないで、同じです。
達成するためのサイクル:結果の分析:
- あなたは右のサブツリーをお持ちの場合:後続ノードは、左端の値の右の子です。
- それ以外の場合は、見上げます。親ノードが第1の値> XであるためCURは、真夜中のように左。
public Node inorderSuccessor(Node x) {
if(x==null){
return null;
}
if(x.right!=null){
Node tmp=x.right;
while(tmp.left!=null){
tmp=tmp.left;
}
return tmp;
}else{
Node cur=x;
while(cur.parent!=null&&cur!=cur.parent.left){
cur=cur.parent;
}
//cur为null、cur的parent为null
return cur.parent;
}
}