Giả sử chúng ta có một cây tìm kiếm nhị phân và một giá trị đích; chúng ta phải tìm k giá trị trong BST đó gần với mục tiêu nhất. Chúng ta phải lưu ý rằng giá trị mục tiêu là một số dấu phẩy động. Chúng ta có thể giả sử k luôn hợp lệ và k ≤ tổng số nút.
Vì vậy, nếu đầu vào giống như
target =3,714286 và k =2, thì đầu ra sẽ là [4,3]
Để giải quyết vấn đề này, chúng tôi sẽ làm theo các bước sau -
-
Xác định một hàm pushSmaller (), hàm này sẽ lấy nút, ngăn xếp và đích,
-
trong khi nút không hiện diện, hãy làm -
-
if val của node
-
chèn nút vào st
-
node:=right of node
-
-
Nếu không
-
node:=left of node
-
-
-
Xác định một hàm pushLarger (), hàm này sẽ lấy node, stack st, target,
-
trong khi nút trống, hãy làm -
-
if val of node> =target, then -
-
chèn nút vào st
-
node:=left of node
-
-
Nếu không
-
node:=right of node
-
-
-
Từ phương thức chính, thực hiện như sau -
-
Xác định ret mảng
-
Xác định một ngăn xếp nhỏ hơn
-
Xác định một ngăn xếp lớn hơn
-
pushLarger (gốc, lớn hơn, đích)
-
pushSmaller (gốc, nhỏ hơn, đích)
-
trong khi k khác 0, giảm k trong mỗi bước, thực hiện -
-
nếu nhỏ hơn thì không trống và (lớn hơn thì trống hoặc | target - giá trị của phần tử trên cùng của | <| target - phần tử trên cùng của lớn hơn |)
-
curr =phần tử trên cùng của
nhỏ hơn -
xóa phần tử từ nhỏ hơn
-
chèn val của curr vào cuối ret
-
pushSmaller (trái của curr, nhỏ hơn, target)
-
-
Nếu không
-
curr =phần tử hàng đầu của lớn hơn
-
xóa phần tử khỏi lớn hơn
-
chèn val của curr vào cuối ret
-
pushSmaller (bên phải curr, lớn hơn, target)
-
-
-
trả lại ret
Ví dụ
Hãy cùng chúng tôi xem cách triển khai sau để hiểu rõ hơn -
#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)); }
Đầu vào
{4,2,5,1,3}, 3.7142, 2
Đầu ra
[4, 3, ]