220. Contains Duplicate III (M)

2020-11-19  本文已影响0人  Ysgc

Given an array of integers, find out whether there are two distinct indices i and j in the array such that the absolute difference between nums[i] and nums[j] is at most t and the absolute difference between i and j is at most k.

Example 1:

Input: nums = [1,2,3,1], k = 3, t = 0
Output: true
Example 2:

Input: nums = [1,0,1,1], k = 1, t = 2
Output: true
Example 3:

Input: nums = [1,5,9,1,5,9], k = 2, t = 3
Output: false

Constraints:

0 <= nums.length <= 2 * 104
-231 <= nums[i] <= 231 - 1
0 <= k <= 104
0 <= t <= 231 - 1


我的方法:

class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
        multiset<long long int> window;
        
        for (int i=0; i<nums.size(); ++i) {
            long int curr_num = nums[i];
            if (window.size() > k and i-k-1>=0) {
                window.erase(window.lower_bound(nums[i-k-1]));
            }
            
            if (!window.empty()) {
                long int min_num = *(window.begin());
                long int max_num = *(window.rbegin());
                long int left_num = max({min_num, min({max_num, curr_num-t})});
                long int right_num = max({min_num, min({max_num, curr_num+t})});
                    
                long int left = *window.lower_bound(left_num);
                long int right = *window.lower_bound(right_num);
                if (right != right_num) {
                    auto it =  window.lower_bound(right_num);
                    --it;
                    right = *it;
                }
                if (abs(left-curr_num)<=t or abs(right-curr_num)<=t) {
                    return true;
                }
            }
            window.insert(curr_num);
            
        }
        
        return false;
    }
};

Runtime: 80 ms, faster than 14.84% of C++ online submissions for Contains Duplicate III.
Memory Usage: 15.5 MB, less than 12.05% of C++ online submissions for Contains Duplicate III.

主要思想:用multiset当bucket,sliding window里面动态维护一个mutliset,然后对每个元素找window里面的元素-t 和 元素+t 的lowerbound。

    multiset<int> window = {0,2,4,6};
    cout << *window.lower_bound(1) << endl;
    cout << *window.lower_bound(5) << endl;

的输出是2和6

注意事项是


看答案
https://zxi.mytechroad.com/blog/hashtable/leetcode-220-contains-duplicate-iii/
确实是用multiset,但是用法更巧妙:

结合答案的修改:

class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
        multiset<long> window;
        
        for (int i=0; i<nums.size(); ++i) {
            long curr_num = nums[i];
            if (window.size() > k) {
                window.erase(window.lower_bound(nums[i-k-1]));
            }
            
            auto it = window.insert(curr_num);
            if (it != window.begin() and curr_num-*prev(it) <= t){
                return true;
            }
            if (next(it) != window.end() and *next(it)-curr_num <= t){
                return true;
            }
        }
        
        return false;
    }
};

NOTE:

上一篇下一篇

猜你喜欢

热点阅读