1. 程式人生 > >[LeetCode] Contains Duplicate III

[LeetCode] 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 };