思路:
用二叉树维护一个滑动窗口
用最值来剪枝
主要涉及平衡二叉树删除 插入 查找,没有做平衡旋转操作,这道题目的用例可能没有考察这方面的性能
class Solution {
public:
typedef struct NODE {
struct NODE* left;
struct NODE* right;
int val;
NODE(int _val) :left(NULL), right(NULL), val(_val) {
}
}NODE;
NODE* head = NULL;
int windowCount = 0;
int max, min;
void insertToTree(int x) {
if (windowCount == 0) {
min = x; max = x;
}
windowCount++;
if (head == NULL) {
head = new NODE(x);
return;
}
NODE* p = head;
while (p != NULL) {
if (x > p->val) {
if (NULL == p->right) {
p->right = new NODE(x);
break;
}
else {
p = p->right;
}
}
else {
if (NULL == p->left) {
p->left = new NODE(x);
break;
}
else {
p = p->left;
}
}
}
}
void updateMax() {
NODE* p = head;
while (NULL != p) {
max = p->val;
p = p->right;
}
}
void updateMin() {
NODE* p = head;
while (NULL != p) {
min = p->val;
p = p->left;
}
}
void deleteFromTree(int x) {
windowCount--;
//find x
NODE* p = head, *pre = NULL;
while (NULL != p && p->val != x) {
if (x > p->val) {
pre = p;
p = p->right;
}
else {
pre = p;
p = p->left;
}
}
if (p == NULL) {
return;
}
//leaf node ?
if (p->right == NULL && p->left == NULL) {
if (pre) {
pre->left = pre->left == p ? NULL : pre->left;
pre->right = pre->right == p ? NULL : pre->right;
}
else {
head = NULL;
}
delete p;
}
else //have one child
if (p->right == NULL || p->left == NULL) {
if (pre) {
pre->left = pre->left == p ? (p->right == NULL ? p->left : p->right) : pre->left;
pre->right = pre->right == p ? (p->right == NULL ? p->left : p->right) : pre->right;
}
else {
head = p->right == NULL ? p->left : p->right;
}
delete p;
}
else
{
//both child, i will exchange the right child's left chird
NODE* q = p->right; pre = p;
while (q->left != NULL) {
pre = q;
q = q->left;
}
int temp = p->val; p->val = q->val; q->val = temp;
//if pre is q, we need update right chird or we need update left
if (pre == p) {
p->right = q->right;
delete q;
}
else {
pre->left = q->right;
delete q;
}
}
update:
if (x == max) {
updateMax();
}
if (x == min) {
updateMin();
}
}
bool find(int x, int t) {
bool ret = false;
NODE* p = head;
while (p != NULL) {
if (p->val == x) return true;
if (x > p->val) {
if (NULL == p->right) {
break;
}
else {
if (labs((long)x - (long)p->val) <= t) {
ret = true;
break;
}
p = p->right;
}
}
else {
if (NULL == p->left) {
break;
}
else {
if (labs((long)x - (long)p->val) <= t) {
ret = true;
break;
}
p = p->left;
}
}
}
return ret;
}
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
int begin = 0;
for (int i = 0; i < nums.size(); ++i) {
if (windowCount >= k + 1) {
deleteFromTree(nums[begin++]);
}
if (windowCount != 0) {
if (labs((long)nums[i] - (long)min) <= t || labs((long)nums[i] - (long)max) <= t)
return true;
else {
if (find(nums[i], t)) {
return true;
}
}
}
insertToTree(nums[i]);
max = nums[i] > max ? nums[i] : max;
min = nums[i] < min ? nums[i] : min;
}
return false;
}
};