トピックの背景
対象時に何か間違ったのベースケースは比較的理解不足で、その後、デバッグを思考の方法でトピックを紹介注ぎ、そしてその逆の考え方が明確になり戻ってきます。あまり話をしなかった、例を参照してください
オリジナルタイトルリンク:https://leetcode-cn.com/problems/delete-node-in-a-bst/description/を
タイトル説明
バイナリサーチツリーのルートノードの所与のルートと値キーを、バイナリサーチツリー削除キーノードに対応し、かつ同じ二分探索木の特性ことを確認してください。(おそらく更新される)のバイナリ検索ツリーのルートノードへの参照を返します。
:一般的には、削除ノードは2つのステップに分けることができ
、削除するノードを見つけ、まず
見つかった場合、それを削除します。
説明:アルゴリズムの時間複雑度は、O(h)は、hは木の高さが必要です。
例:
root = [8,5,6,3,7,null,9]
key = 5
8
/ \
5 6
/ \ \
3 7 9
给定需要删除的节点值是 5,所以我们首先找到 5 这个节点,然后删除它。
一个正确的答案是 [8,7,6,3,null,null,9], 如下图所示。
8
/ \
7 6
/ \
3 9
另一个正确答案是 [8,3,6,null,7,null,9]。
8
/ \
3 6
\ \
7 9
思考
子ノード、単に削除がない場合:ステップ1は、
ノードを削除したい場合は、唯一の子ノードを持っている、ノードはこの子ノードと交換することが削除されます。STEP2
STEP3:ノードは削除したい場合は、ノードを右から削除し、2人の子供を持っています最低限の枝を見つけ、そのノードが削除されるように置換されます
コードに直接来ます:
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
return null;
}
if (key < root.val){
root.left = deleteNode(root.left,key);
return root;
}else if (key > root.val){
root.right = deleteNode(root.right,key);
return root;
}else {
if (root.left == null || root.right == null){
root = root.left == null?root.right:root.left;
}else {
TreeNode cur = root.right;
while (cur.left != null){
cur = cur.left;
}
root.val = cur.val;
root.right = deleteNode(root.right,cur.val);
}
}
return root;
}
}
まず考えることができ、一時的に下品なやり方で木に割り当てられ、その後、我々は、デバッグに始まりました
public static void main(String[] args) {
Solution solution = new Solution();
TreeNode treeNode1 = new TreeNode(8);
TreeNode treeNode2 = new TreeNode(5);
TreeNode treeNode3 = new TreeNode(6);
TreeNode treeNode4 = new TreeNode(3);
TreeNode treeNode5 = new TreeNode(7);
TreeNode treeNode6 = new TreeNode(9);
treeNode1.left = treeNode2;
treeNode1.right = treeNode3;
treeNode2.left = treeNode4;
treeNode2.right = treeNode5;
treeNode3.left =null;
treeNode3.right = treeNode6;
TreeNode treeNode = solution.deleteNode(treeNode1, 5);
}
まず、root.val値が8で、キーの値は、反復に、5未満であります
今回は、root.valは5であり、この時間は、最初のサブブランチがあり、この時点で決定するために、サブブランチがあるかどうかを判断、次の分岐に進み、もしあれば、我々は、ここに右の分岐枝を残しているかどうかそれから決定し、その後、我々は削除する権利枝の値をカバーするでない場合は、反復を続けるために、あなたは、私たちの権利の枝が、削除したい元の場所を置き換えるために、この時点で見ることができます。
しかし、右の分岐がある、削除されていない、我々は枝を運営する権利を持つことになり、ダウン反復継続しました
ここでも、これはこれまで、何のサブブランチを発見しに来て、それは彼にはnullを与えるだろう。このとき、上のシーケンス右。このアイデアと一緒に行くためには、業務プロセスを整理することができます。
話題の種類の明確なアイデアがある場合は、あなたが自分自身のフローチャートを通過することができます、あなたはより良いこれらのトピックを探求し、自分のアイデアを通じて、この方法を理解する必要はありません。
あなたを助けることを望みます!