-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsolution.cpp
More file actions
93 lines (87 loc) · 2.73 KB
/
Copy pathsolution.cpp
File metadata and controls
93 lines (87 loc) · 2.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
class Node {
public:
int data;
Node* left;
Node* right;
Node(int val) {
data = val;
left = NULL;
right = NULL;
}
};
*/
#include <vector>
#include <stack>
#include <cmath>
using namespace std;
class Solution {
private:
// push path for predecessors: nodes with val <= target (go right to find larger <= target)
void initPred(Node* root, int target, stack<Node*>& st) {
while (root) {
if (root->data <= target) {
st.push(root);
root = root->right;
} else {
root = root->left;
}
}
}
// push path for successors: nodes with val > target (go left to find smaller > target)
void initSucc(Node* root, int target, stack<Node*>& st) {
while (root) {
if (root->data > target) {
st.push(root);
root = root->left;
} else {
root = root->right;
}
}
}
// get next predecessor (largest value < = previous)
int getNextPred(stack<Node*>& st) {
Node* node = st.top(); st.pop();
int val = node->data;
node = node->left; // after visiting node, predecessor continues on left subtree's rightmost
while (node) {
st.push(node);
node = node->right;
}
return val;
}
// get next successor (smallest value > previous)
int getNextSucc(stack<Node*>& st) {
Node* node = st.top(); st.pop();
int val = node->data;
node = node->right; // after visiting node, successor continues on right subtree's leftmost
while (node) {
st.push(node);
node = node->left;
}
return val;
}
public:
vector<int> getKClosest(Node* root, int target, int k) {
vector<int> res;
if (!root || k <= 0) return res;
stack<Node*> pred, succ;
initPred(root, target, pred);
initSucc(root, target, succ);
while (k-- > 0) {
if (pred.empty() && succ.empty()) break;
else if (pred.empty()) res.push_back(getNextSucc(succ));
else if (succ.empty()) res.push_back(getNextPred(pred));
else {
int pval = pred.top()->data;
int sval = succ.top()->data;
int pdiff = abs(pval - target);
int sdiff = abs(sval - target);
// tie: choose smaller value => pick predecessor
if (pdiff <= sdiff) res.push_back(getNextPred(pred));
else res.push_back(getNextSucc(succ));
}
}
return res;
}
};