LeetCode OJ: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的两个数的值小于t就可以满足要求,返回true。 这里使用multiset来实现,因为其底层使用的是红黑数,一斤排好序了,而且查找性能好,不会出现out of time的情况,主要的想法是遍历vector,当multiset的大小小于k的时候插入,判断当前值在整个set中是否有值与其相差t及以下,由于存在lower_bound,还是比较方便的。

 1 class Solution {
 2 public:
 3     bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
 4         multiset<long long> ret;
 5         int sz = nums.size();
 6         for (int i = 0; i < sz; ++i){
 7             if (ret.size() == k + 1)
 8                 ret.erase(ret.find(nums[i - k -1]));
 9             auto lb = ret.lower_bound(nums[i] - t); //  这个表达式规定了*lb - nums[i] > -t
10             if (lb != ret.end() && *lb - nums[i] <= t)return true;  //这个规定了*lb - num[i] < t;
11             ret.insert(nums[i]);
12         }
13         return false;
14     }
15 };

 感觉以前写的c++的版本写的比较怪,下面是java写的,其实维持一个长度为k的窗口不一定需要用multiSet直接使用java中的treeSet接可以维持一个,lower_bound以及upper_bound函数实际上也是不需要的,代码如下所示:

 1 public class Solution {
 2     public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
 3         if(k < 1|| t < 0 || nums == null || nums.length < 2)
 4             return false;
 5         SortedSet<Long> set = new TreeSet<Long>();
 6         for(int i = 0; i < nums.length; ++i){
 7             SortedSet<Long> subSet = set.subSet((long)nums[i] - t, (long)nums[i] + t + 1);
 8             if(!subSet.isEmpty())
 9                 return true;
10             if(i >= k){//维持一个长度为k的窗口,就是说窗口一只向前滑动
11                 set.remove((long)nums[i-k]);
12             }
13             set.add((long)nums[i]);
14         }
15         return false;
16     }
17 }
原文地址:https://www.cnblogs.com/-wang-cheng/p/4887646.html