给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ。
思路
- 双指针:略过。
- Set:维护一个大小为k的set,由于set自动排序的特性,可以找出不小于nums[i]-t的值,然后判断该值是否同时不大于nums[i]+t。
- 哈希+桶:将nums元素分散到大小为t+1的桶中,然后以桶id作为键,nums[i]作为值存入hash表,只需要查找nums[i]所在的桶和相邻的两个桶即可。
代码(C++)
Set
1 2 3 4 5 6 7 8 9 10 11 12
| if(k<1 || nums.size()<2 || t<0) return false; set<int> s; for(int i=0;i<nums.size();i++) { auto ps=s.lower_bound(nums[i]-t); if(ps!=s.end() && abs((*ps)-nums[i])<=t) return true; s.insert(nums[i]); if(s.size()>k) s.erase(nums[i-k]); } return false;
|
哈希+桶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| int getid(int n,int s) { return n<0?(n+1)/s-1:n/s; }
if(k<1 || nums.size()<2 || t<0) return false; unordered_map<int,int> m; int sb=t+1; int id; int n; for(int i=0;i<nums.size();i++) { n=nums[i]; id=getid(n,sb); if(m.count(id)) return true; if(m.count(id-1) && n-m[id-1]<=t) return true; if(m.count(id+1) && m[id+1]-n<=t) return true; m[id]=n; if(m.size()>k) m.erase(m.find(getid(nums[i-k],sb))); } return false;
|