# 220. Contains Duplicate III 題目:<https://leetcode.com/problems/contains-duplicate-iii/> 解法:使用 sliding window 加上 binary search tree 來解,依照題目 indexDiff 的限制,以 sliding window 的概念,依序搜尋第 i - indexDiff 到第 i - 1 個元素是否符合 valueDiff 條件,為了加速搜尋使用 AVL tree 來搜尋,若找不到符合條件的元素,則刪除 AVL tree 中第 i - indexDiff 個元素,加入第 i 個元素,在接續往下搜尋。 Python3: ``` python 3 class AVLNode(object): def __init__(self, val): self.val = val self.left = None self.right = None self.height = 1 class AVLTree(object): def insertNode(self, node, val): if not node: return AVLNode(val) if val < node.val: node.left = self.insertNode(node.left, val) else: node.right = self.insertNode(node.right, val) return self.balance(node) def deleteNode(self, node, val): if node is None: return node if val < node.val: node.left = self.deleteNode(node.left, val) elif val > node.val: node.right = self.deleteNode(node.right, val) else: if node.left is None: return node.right elif node.right is None: return node.left else: cur = node.right while cur.left: cur = cur.left; node.val = cur.val node.right = self.deleteNode(node.right, cur.val) return self.balance(node) def balance(self, node): node.height = 1 + max(self.getHeight(node.left), self.getHeight(node.right)) balanceFactor = self.getHeight(node.left) - self.getHeight(node.right) if balanceFactor > 1: if self.getHeight(node.left.left) > self.getHeight(node.left.right): return self.rightRotate(node) else: node.left = self.leftRotate(node.left) return self.rightRotate(node) if balanceFactor < -1: if self.getHeight(node.right.right) > self.getHeight(node.right.left): return self.leftRotate(node) else: node.right = self.rightRotate(node.right) return self.leftRotate(node) return node def leftRotate(self, node): top = node.right node.right = top.left top.left = node node.height = 1 + max(self.getHeight(node.left), self.getHeight(node.right)) top.height = 1 + max(self.getHeight(top.left), self.getHeight(top.right)) return top def rightRotate(self, node): top = node.left node.left = top.right top.right = node node.height = 1 + max(self.getHeight(node.left), self.getHeight(node.right)) top.height = 1 + max(self.getHeight(top.left), self.getHeight(top.right)) return top def getHeight(self, node): if not node: return 0 return node.height class Solution: def containsNearbyAlmostDuplicate(self, nums: list[int], indexDiff: int, valueDiff: int) -> bool: root = None for i in range(len(nums)): cur = root while cur: if nums[i] < cur.val - valueDiff: cur = cur.left elif nums[i] > cur.val + valueDiff: cur = cur.right else: return True root = AVLTree().insertNode(root, nums[i]) if i >= indexDiff: root = AVLTree().deleteNode(root, nums[i-indexDiff]) return False if __name__ == '__main__': nums = [1,5,9,1,5,9] indexDiff = 2 valueDiff = 3 ans = Solution().containsNearbyAlmostDuplicate(nums, indexDiff, valueDiff) print(ans) ``` C: ``` c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> int max(int a, int b) { return (a > b) ? a : b; } typedef struct AVLNode { int val; struct AVLNode *left; struct AVLNode *right; int height; } AVLNode; int getHeight(AVLNode *node) { if (node == NULL) return 0; return node->height; } AVLNode* leftRotate(AVLNode *node) { AVLNode *top = node->right; node->right = top->left; top->left = node; node->height = 1 + max(getHeight(node->left), getHeight(node->right)); top->height = 1 + max(getHeight(top->left), getHeight(top->right)); return top; } AVLNode* rightRotate(AVLNode *node) { AVLNode *top = node->left; node->left = top->right; top->right = node; node->height = 1 + max(getHeight(node->left), getHeight(node->right)); top->height = 1 + max(getHeight(top->left), getHeight(top->right)); return top; } AVLNode* balance(AVLNode *node) { node->height = 1 + max(getHeight(node->left), getHeight(node->right)); int balanceFactor = getHeight(node->left) - getHeight(node->right); if (balanceFactor > 1) { if (getHeight(node->left->left) > getHeight(node->left->right)) { return rightRotate(node); } else { node->left = leftRotate(node->left); return rightRotate(node); } } if (balanceFactor < -1) { if (getHeight(node->right->right) > getHeight(node->right->left)) { return leftRotate(node); } else { node->right = rightRotate(node->right); return leftRotate(node); } } return node; } AVLNode* insertNode(AVLNode *node, int val) { if (node == NULL) { node = (AVLNode*)malloc(sizeof(AVLNode)); node->val = val; node->left = NULL; node->right = NULL; node->height = 1; return node; } if (val < node->val) node->left = insertNode(node->left, val); else if (val > node->val) node->right = insertNode(node->right, val); return balance(node); } AVLNode* deleteNode(AVLNode *node, int val) { if (node == NULL) return node; if (val < node->val) node->left = deleteNode(node->left, val); else if (val > node->val) node->right = deleteNode(node->right, val); else { if (node->left == NULL) { AVLNode *cur = node->right; free(node); return cur; } else if (node->right == NULL) { AVLNode *cur = node->left; free(node); return cur; } else { AVLNode *cur = node->right; while (cur->left != NULL) cur = cur->left; node->val = cur->val; node->right = deleteNode(node->right, cur->val); } } return balance(node); } // Print the tree void printPreOrder(AVLNode *root) { if (root != NULL) { printf("%d ", root->val); printPreOrder(root->left); printPreOrder(root->right); } } bool containsNearbyAlmostDuplicate(int* nums, int numsSize, int indexDiff, int valueDiff) { AVLNode *root = NULL; for (int i = 0; i < numsSize; i++) { AVLNode *cur = root; while (cur != NULL) { if (nums[i] < cur->val - valueDiff) cur = cur->left; else if (nums[i] > cur->val + valueDiff) cur = cur->right; else return true; } root = insertNode(root, nums[i]); if (i >= indexDiff) root = deleteNode(root, nums[i-indexDiff]); } return false; } int main() { int nums[] = {1,5,9,1,5,9}; int numsSize = sizeof(nums) / sizeof(nums[0]); int indexDiff = 2, valueDiff = 3; bool ans = containsNearbyAlmostDuplicate(nums, numsSize, indexDiff, valueDiff); printf("%s\n", ans ? "True" : "False"); return 0; } ``` ###### tags: `leetcode` `binary tree` `binary search tree` `AVL tree` `sliding window`