-
Notifications
You must be signed in to change notification settings - Fork 92
/
ContainsDuplicateIII220.java
74 lines (65 loc) · 2.56 KB
/
ContainsDuplicateIII220.java
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/**
* 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.
*/
public class ContainsDuplicateIII220 {
// // TLE
// public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
// for (int i=0; i<nums.length; i++) {
// for (int j=i+1; j<nums.length && j<=i+k; j++) {
// if (Math.abs((long)nums[i] - (long)nums[j]) <= (long)t) return true;
// }
// }
//
// return false;
// }
/**
* https://leetcode.com/problems/contains-duplicate-iii/solution/
*/
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
TreeSet<Integer> set = new TreeSet<>();
for (int i = 0; i < nums.length; ++i) {
// Find the successor of current element
Integer s = set.ceiling(nums[i]);
if (s != null && s <= nums[i] + t) return true;
// Find the predecessor of current element
Integer g = set.floor(nums[i]);
if (g != null && nums[i] <= g + t) return true;
set.add(nums[i]);
if (set.size() > k) {
set.remove(nums[i - k]);
}
}
return false;
}
/**
* https://leetcode.com/problems/contains-duplicate-iii/solution/
*/
// Get the ID of the bucket from element value x and bucket width w
// In Java, `-3 / 5 = 0` and but we need `-3 / 5 = -1`.
private long getID(long x, long w) {
return x < 0 ? (x + 1) / w - 1 : x / w;
}
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (t < 0) return false;
Map<Long, Long> d = new HashMap<>();
long w = (long)t + 1;
for (int i = 0; i < nums.length; ++i) {
long m = getID(nums[i], w);
// check if bucket m is empty, each bucket may contain at most one element
if (d.containsKey(m))
return true;
// check the neighbor buckets for almost duplicate
if (d.containsKey(m - 1) && Math.abs(nums[i] - d.get(m - 1)) < w)
return true;
if (d.containsKey(m + 1) && Math.abs(nums[i] - d.get(m + 1)) < w)
return true;
// now bucket m is empty and no almost duplicate in neighbor buckets
d.put(m, (long)nums[i]);
if (i >= k) d.remove(getID(nums[i - k], w));
}
return false;
}
}