夜刷:平衡二叉樹的基本操作
思路:
用二叉樹維護一個滑動視窗
用最值來剪枝
主要涉及平衡二叉樹刪除 插入 查詢,沒有做平衡旋轉操作,這道題目的用例可能沒有考察這方面的效能
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;
}
};
相關文章
- 平衡二叉樹二叉樹
- 排序二叉樹和平衡二叉樹排序二叉樹
- 平衡二叉樹(AVL)二叉樹
- 平衡樹和二叉樹的區別二叉樹
- 手擼二叉樹——AVL平衡二叉樹二叉樹
- 平衡二叉樹,B樹,B+樹二叉樹
- Python 樹表查詢_千樹萬樹梨花開,忽如一夜春風來(二叉排序樹、平衡二叉樹)Python排序二叉樹
- 平衡二叉樹(AVL樹)和 二叉排序樹轉化為平衡二叉樹 及C語言實現二叉樹排序C語言
- 110. 平衡二叉樹二叉樹
- 自動平衡二叉樹的構建-AVL樹二叉樹
- 十三、Mysql之平衡二叉樹(AVL樹)MySql二叉樹
- 平衡二叉樹(AVL樹),原來如此!!!二叉樹
- 平衡二叉查詢樹:紅黑樹
- 二叉堆、BST 與平衡樹
- JZ-039-平衡二叉樹二叉樹
- LeetCode-110-平衡二叉樹LeetCode二叉樹
- 二叉樹的深度、寬度遍歷及平衡樹二叉樹
- Java實現紅黑樹(平衡二叉樹)Java二叉樹
- 滿二叉樹、完全二叉樹、平衡二叉樹、二叉搜尋樹(二叉查詢樹)和最優二叉樹二叉樹
- 程式碼隨想錄——二叉樹-12.平衡二叉樹二叉樹
- 資料結構-平衡二叉樹資料結構二叉樹
- 每日一練(28):平衡二叉樹二叉樹
- python實現非平衡二叉樹Python二叉樹
- 二叉平衡樹 python 列表 遞迴Python遞迴
- [Python手撕]判斷平衡二叉樹Python二叉樹
- 學習筆記——二叉平衡樹(BST)筆記
- 手寫AVL平衡二叉搜尋樹
- 遞迴判斷是否二叉平衡樹遞迴
- 這兩天寫的一個二叉平衡樹
- 二叉樹的基本運算2二叉樹
- Java 樹結構實際應用 四(平衡二叉樹/AVL樹)Java二叉樹
- 如何判斷一棵樹是否是二叉平衡樹~
- 資料結構之樹結構概述(含滿二叉樹、完全二叉樹、平衡二叉樹、二叉搜尋樹、紅黑樹、B-樹、B+樹、B*樹)資料結構二叉樹
- 二叉搜尋樹的操作集
- 二叉樹基本原理二叉樹
- JZ79 判斷是不是平衡二叉樹二叉樹
- 24. 平衡二叉樹,及其程式碼實現二叉樹
- leetcode-1382. 將二叉搜尋樹變平衡LeetCode