[leetcode ]220.Contains Duplicate III
2015-07-25 16:19
465 查看
题目:
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。
思路:
这是第二道题继续延伸过来。第二道题请参考我的上一篇博客/article/9676047.html。
这道题变化的是不是判断两个数相等,而是两个数相差的范围小于等于某个给定值。我们上一题的思路是使用hash来记录窗口大小是k的数据。依旧使用hash的方法来完成。我们其实可以将题目转变为与上一题一样的解法。比如我们现在有两个数字m,n,如果m与n满足两者相差小于等于k,那么我们可以得到的是m / k == n / k 如果m是k的倍数,并且n也是k的倍数,那么可能|m/k- n/k| ==1,综合起来就是|m/k- n/k| <=1.也就是说我们将每个数字除上k,那么就相当于压缩了数据到第二题的情形。
所以这次对于每个数字nums[i]进行先除去k的操作,得到m,如果之前窗口中有满足条件的结果值,那么有三种可能:
key值m在窗口中已经记录了值,这就代表着nums[j] / k也等于m,所以nums[j]与nums[i]满足条件。
key值m-1在窗口中记录了值,并且abs(map[m-1] - nums[i]) <= t;
key值m+1在窗口中记录了值,并且abs(map[m+1] - nums[i]) <= t;
需要考虑负数情况,比如-3,3如果t=4,那么-3/4==0,3/4==0,然-3,3并不满足条件,本文中将数字全部加上int的最大值转变为long long类型,确保全部非负。
以上。
代码如下:
还可以使用二叉搜索树(红黑树)来进行查找操作。做法是使用set来保存前k个元素,到达第k+1个元素的时候,查看大于等于nums[k+1] - t的第一个元素,使用STL的lower_bound进行查找。然后判断这个元素是否满足与nums[k+1]的差距在t的范围之内,即abs(nums[k+1] - *iter)是否小于等于t。因为我们使用lower_bound查找的时候,找到的元素比nums[k+1] - t大,但是也有可能太大,所以要查看这个元素与nums[k+1]的距离是否是在t的范围之内。
以上。
代码如下:
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。
思路:
这是第二道题继续延伸过来。第二道题请参考我的上一篇博客/article/9676047.html。
这道题变化的是不是判断两个数相等,而是两个数相差的范围小于等于某个给定值。我们上一题的思路是使用hash来记录窗口大小是k的数据。依旧使用hash的方法来完成。我们其实可以将题目转变为与上一题一样的解法。比如我们现在有两个数字m,n,如果m与n满足两者相差小于等于k,那么我们可以得到的是m / k == n / k 如果m是k的倍数,并且n也是k的倍数,那么可能|m/k- n/k| ==1,综合起来就是|m/k- n/k| <=1.也就是说我们将每个数字除上k,那么就相当于压缩了数据到第二题的情形。
所以这次对于每个数字nums[i]进行先除去k的操作,得到m,如果之前窗口中有满足条件的结果值,那么有三种可能:
key值m在窗口中已经记录了值,这就代表着nums[j] / k也等于m,所以nums[j]与nums[i]满足条件。
key值m-1在窗口中记录了值,并且abs(map[m-1] - nums[i]) <= t;
key值m+1在窗口中记录了值,并且abs(map[m+1] - nums[i]) <= t;
需要考虑负数情况,比如-3,3如果t=4,那么-3/4==0,3/4==0,然-3,3并不满足条件,本文中将数字全部加上int的最大值转变为long long类型,确保全部非负。
以上。
代码如下:
class Solution { public: bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) { if(nums.size() == 0 || k <= 0 || t < 0)return false; unordered_map<long long,int> window; for(int i = 0; i < nums.size(); i++) { long long bucket = ((long long)nums[i] + INT_MAX)/(t + 1); if(window.find(bucket) != window.end() || (window.find(bucket - 1) != window.end() && abs((long long)nums[i] - window[bucket - 1]) <= t) || (window.find(bucket + 1) != window.end() && abs((long long)nums[i] - window[bucket + 1]) <= t)) return true; if(window.size() == k) { long long last_bucket = ((long long)nums[i - k] + INT_MAX)/(t + 1); window.erase(last_bucket); } window[bucket] = nums[i]; } return false; } };
还可以使用二叉搜索树(红黑树)来进行查找操作。做法是使用set来保存前k个元素,到达第k+1个元素的时候,查看大于等于nums[k+1] - t的第一个元素,使用STL的lower_bound进行查找。然后判断这个元素是否满足与nums[k+1]的差距在t的范围之内,即abs(nums[k+1] - *iter)是否小于等于t。因为我们使用lower_bound查找的时候,找到的元素比nums[k+1] - t大,但是也有可能太大,所以要查看这个元素与nums[k+1]的距离是否是在t的范围之内。
以上。
代码如下:
class Solution { public: bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) { if(nums.size() == 0 || k <= 0 || t < 0)return false; set<int> window; int size = nums.size(); for(int i = 0; i < size; i++) { if(i > k) { window.erase(nums[i - k - 1]); } auto iter = window.lower_bound(nums[i] - t); if(iter != window.end() && abs(nums[i] - *iter) <= t) return true; window.insert(nums[i]); } return false; } };
相关文章推荐
- Snail—OC学习之空变量的表示
- Snail—OC学习之NSNumber
- Snail—OC学习之日期NSDate
- UVa 11853 - Paintball(DFS)
- HDU 1302 The Snail
- http://blog.csdn.net/ooflywing/article/details/5616311
- HDU 2674-- N!Again【技巧】
- 最具体的历史centos下一个 postfix + extmail + dovecot + maildrop 安装注意事项2014更新
- HDU 5289 2015 Multi-University Training Contest 1 1002 RMQ+二分
- hdoj 2674 N!Again 【好题】
- Leetcode 11 Container With Most Water
- uva12546. LCM Pair Sum
- HDU 2473 Junk-Mail Filter (并查集的删除操作)
- 可笑的unsigned double http://blog.csdn.net/suhuaiqiang_janlay/article/details/6078034
- 动态规划,而已! CodeForces 433B - Kuriyama Mirai's Stones
- udp socket bind fail
- ZOJ 3675 Trim the Nails(bfs)
- 使用UltraISO制作启动盘装Windows系统详细教程
- AIX7.1+11.2.0.4RAC实施
- 如何提升 RailS 应用的性能?