夜刷:平衡二叉树的基本操作

在这里插入图片描述
在这里插入图片描述

思路:
用二叉树维护一个滑动窗口
用最值来剪枝
主要涉及平衡二叉树删除 插入 查找,没有做平衡旋转操作,这道题目的用例可能没有考察这方面的性能

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;
	}
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值