Question:学习
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.spa
最开始考虑双层循环遍历,可是代码提交上去提示超时,想一想也是,双层循环时间复杂度是O(n^2)。后考虑使用TreeSet,时间复杂度为O(nlogk).code
Code: blog
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) { if (k < 1 || t < 0 || nums == null || nums.length < 2){ return false; } SortedSet<Long> record = new TreeSet<>(); for (int i = 0; i < nums.length; i++) { SortedSet<Long> sets = record.subSet((long) nums[i] - t, (long) nums[i] + t + 1); if(!sets.isEmpty()){ return true; } record.add((long)nums[i]); if(record.size() == k + 1){ record.remove((long)nums[i-k]); } } return false; }
提交上去后显示执行时间为51ms. 不是很理想,查看最优的代码,以下(执行时间是28ms,顺便也学习下)rem
public class Solution { public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) { if (nums == null || nums.length == 0 || t < 0 || k < 0) return false; if (k == 0) return false; Map<Long, Long> map = new HashMap<>(); long w = (long) t + 1; for (int i = 0; i < nums.length; i++) { long bucket = getBucket(nums[i], w); if (map.containsKey(bucket)) { return true; } if (map.containsKey(bucket - 1) && (Math.abs(map.get(bucket-1) - (long) nums[i]) <= t)) { return true; } if (map.containsKey(bucket + 1) && (Math.abs(map.get(bucket+1) - (long) nums[i]) <= t)) { return true; } map.put(bucket, (long) nums[i]); if (i >= k) { map.remove(getBucket(nums[i-k], w)); } } return false; } private long getBucket(long num, long w) { return (long) (num < 0 ? (num + 1)/w - 1 : num / w); } }