Contains Duplicate III
Given an array of integers, find out whether there are two distinct indices i and j in the array such that the difference between nums[i] and nums[j] is at most t and the difference between i and j is at most k.
一開始理解錯題目了,還以為是要求所有的數對都必須符合要求,一直超時。其實題目是問是不是存在一個符合條件的數對,所以就容易多了,維護一個大小為 k 的二叉搜索樹,來一個新的元素時,在BST上二分搜索有沒有符合條件的數對,動態更新這個BST。因為BST的大小為 k 或不超過 k,所以這里面的數下標的差值一定是符合條件的。還有幾點要注意的就是nums[i]與nums[j]的差值的是絕對值,所以要分別找lower_bound跟upper_bound,數據比較坑爹,為了防止溢出,容器用long long類型的。
1 class Solution { 2 public: 3 bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) { 4 multiset<long long> bst; 5 for (int i = 0; i < nums.size(); ++i) { 6 if (bst.size() == k + 1) bst.erase(bst.find(nums[i - k - 1])); 7 auto lb = bst.lower_bound(nums[i]); 8 if (lb != bst.end() && abs(*lb - nums[i]) <= t) return true; 9 auto ub = bst.upper_bound(nums[i]); 10 if (ub != bst.begin() && abs(*(--ub) - nums[i]) <= t) return true; 11 bst.insert(nums[i]); 12 } 13 return false; 14 } 15 };
不用比較兩次,直接找nums[i] - t的lower_bound, 這個值就是與nums[i]差值最近的值。
1 class Solution { 2 public: 3 bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) { 4 multiset<long long> bst; 5 for (int i = 0; i < nums.size(); ++i) { 6 if (bst.size() == k + 1) bst.erase(bst.find(nums[i - k - 1])); 7 auto lb = bst.lower_bound(nums[i] - t); 8 if (lb != bst.end() && *lb - nums[i] <= t) return true; 9 bst.insert(nums[i]); 10 } 11 return false; 12 } 13 };