C++で最も近い二分探索木値II
二分探索木とターゲット値があるとします。そのBSTで、ターゲットに最も近いk個の値を見つける必要があります。目標値は浮動小数点数であることに注意する必要があります。 kは常に有効であり、k≤合計ノードであると想定できます。
したがって、入力が次のような場合
target =3.714286、k =2の場合、出力は[4,3]
になります。これを解決するには、次の手順に従います-
-
関数pushSmaller()を定義します。これにより、ノード、スタックst、およびターゲットが取得されます。
-
ノードが存在しない場合は、-
を実行します-
ノードの値が<ターゲットの場合、-
-
stにノードを挿入
-
ノード:=ノードの右側
-
-
それ以外の場合
-
ノード:=ノードの左側
-
-
-
関数pushLarger()を定義します。これにより、ノード、スタックst、ターゲット、
が取得されます。 -
ノードが空のときに、-
を実行します-
ノードのval>=targetの場合、-
-
stにノードを挿入
-
ノード:=ノードの左側
-
-
それ以外の場合
-
ノード:=ノードの右側
-
-
-
メインの方法から、次のようにします-
-
配列retを定義する
-
スタックを1つ小さく定義します
-
スタックを1つ大きく定義する
-
pushLarger(root、larger、target)
-
pushSmaller(root、smaller、target)
-
kがゼロ以外の場合、各ステップでkを減らし、-
を実行します。-
smallが空ではなく、(largerが空または|target-smallerの最上位要素の値|<| target--largerのtopelement |)
-
curr=小さい方の一番上の要素
-
小さい方から要素を削除する
-
retの最後にcurrのvalを挿入します
-
pushSmaller(currの左側、小さい、ターゲット)
-
-
それ以外の場合
-
curr=大きい方の一番上の要素
-
大きい方から要素を削除する
-
retの最後にcurrのvalを挿入します
-
pushSmaller(currの右側、大きい、ターゲット)
-
-
-
retを返す
例
理解を深めるために、次の実装を見てみましょう-
#include <bits/stdc++.h> using namespace std; void print_vector(vector<auto> v){ cout << "["; for(int i = 0; i<v.size(); i++){ cout << v[i] << ", "; } cout << "]"<<endl; } class TreeNode{ public: int val; TreeNode *left, *right; TreeNode(int data){ val = data; left = NULL; right = NULL; } }; void insert(TreeNode **root, int val){ queue<TreeNode*> q; q.push(*root); while(q.size()){ TreeNode *temp = q.front(); q.pop(); if(!temp->left){ if(val != NULL) temp->left = new TreeNode(val); else temp->left = new TreeNode(0); return; } else{ q.push(temp->left); } if(!temp->right){ if(val != NULL) temp->right = new TreeNode(val); else temp->right = new TreeNode(0); return; } else{ q.push(temp->right); } } } TreeNode *make_tree(vector<int> v){ TreeNode *root = new TreeNode(v[0]); for(int i = 1; i<v.size(); i++){ insert(&root, v[i]); } return root; } class Solution { public: vector<int> closestKValues(TreeNode* root, double target, int k) { vector<int> ret; stack<TreeNode*> smaller; stack<TreeNode*> larger; pushLarger(root, larger, target); pushSmaller(root, smaller, target); while (k--) { if (!smaller.empty() && (larger.empty() || (abs(target - smaller.top()->val) < abs(target - larger.top()->val)))) { TreeNode* curr = smaller.top(); smaller.pop(); ret.push_back(curr->val); pushSmaller(curr->left, smaller, target); } else { TreeNode* curr = larger.top(); larger.pop(); ret.push_back(curr->val); pushLarger(curr->right, larger, target); } } return ret; } void pushSmaller(TreeNode* node, stack <TreeNode*>& st, double target){ while (node) { if (node->val < target) { st.push(node); node = node->right; } else { node = node->left; } } } void pushLarger(TreeNode* node, stack <TreeNode*>& st, double target){ while (node) { if (node->val >= target) { st.push(node); node = node->left; } else node = node->right; } } }; main(){ Solution ob; vector<int> v = {4,2,5,1,3}; TreeNode *root = make_tree(v); print_vector(ob.closestKValues(root, 3.7142, 2)); }
入力
{4,2,5,1,3}, 3.7142, 2
出力
[4, 3, ]
-
C++の二分探索木で最小値のノードを見つけます
1つの二分探索木があるとします。二分探索木で最小要素を見つける必要があります。したがって、BSTが以下のような場合- 最小要素は1になります。 左のサブツリーは常に小さい要素を保持していることがわかっています。したがって、左がnullになるまで左のサブツリーを何度もトラバースすると、最小の要素を見つけることができます。 例 #include<iostream> using namespace std; class node{ public: node *left;
-
C ++プログラムでの二分探索?
二分探索は、半区間探索、対数探索、または二分探索とも呼ばれ、ソートされた配列内のターゲット値の位置を見つける検索アルゴリズムです。二分探索は、ターゲット値を配列の中央の要素と比較します。それらが等しくない場合、ターゲットが存在できない半分が削除され、残りの半分で検索が続行され、再び中央の要素がターゲット値と比較され、ターゲット値が見つかるまでこれが繰り返されます。残りの半分が空の状態で検索が終了した場合、ターゲットは配列に含まれていません。アイデアは単純ですが、バイナリ検索を正しく実装するには、特に配列の値が範囲内の整数のすべてではない場合、終了条件と中間点の計算に関する微妙な点に注意する必要