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); } }