LeetCode-存在重复元素 III-220--排序

给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ。

示例 1:

输入: nums = [1,2,3,1], k = 3, t = 0
输出: true

示例 2:

输入: nums = [1,0,1,1], k = 1, t = 2
输出: true

示例 3:

输入: nums = [1,5,9,1,5,9], k = 2, t = 3
输出: false

思路:
首先会想到的是通过窗口的滑动来判断,但是时间复杂度太高了,超时。
第二种思路,是采用桶排序的思想,分析题目可知需要在k大小的窗口上找到两个数的差要小于t,
所以就可以将数分桶,桶大小为t,若存在两个数在一个桶范围内,则满足要求,
还有一种情况在相邻桶之间存在两个数的差小于等于t。

代码:

class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
    	//使用哈希表来做桶存储元素
        Map<Long, Long> map = new HashMap<>();
        long w  = (long)t + 1;
        
        for (int i = 0; i < nums.length; i++) {
        	long id = getId(nums[i], w);
        	
        	//在桶中已经存在了
        	if (map.containsKey(id)) {
        		return true;
        	}
        	//判断相邻桶
        	if (map.containsKey(id - 1) && Math.abs(map.get(id - 1) - nums[i]) < w) {
        		return true;
        	}
        	if (map.containsKey(id + 1) && Math.abs(map.get(id + 1) - nums[i]) < w) {
        		return true;
        	}
        	
        	map.put(id, (long)nums[i]);
        	
        	if (i >= k){ // 保持窗口太小为k
        		map.remove(getId(nums[i - k], w));
        	}
        }
        return false;
    }
    
    //计算数所在桶的id
	private long getId(int i, long w) {
		return i < 0 ? (i + 1) / w - 1 : i / w;
	}
}
发布了84 篇原创文章 · 获赞 50 · 访问量 7046

猜你喜欢

转载自blog.csdn.net/qq_43115606/article/details/103450128