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 ++プログラムでの二分探索?
二分探索は、半区間探索、対数探索、または二分探索とも呼ばれ、ソートされた配列内のターゲット値の位置を見つける検索アルゴリズムです。二分探索は、ターゲット値を配列の中央の要素と比較します。それらが等しくない場合、ターゲットが存在できない半分が削除され、残りの半分で検索が続行され、再び中央の要素がターゲット値と比較され、ターゲット値が見つかるまでこれが繰り返されます。残りの半分が空の状態で検索が終了した場合、ターゲットは配列に含まれていません。アイデアは単純ですが、バイナリ検索を正しく実装するには、特に配列の値が範囲内の整数のすべてではない場合、終了条件と中間点の計算に関する微妙な点に注意する必要