Skip to content

Commit 2ab8d55

Browse files
refactor 220
1 parent 99e4cac commit 2ab8d55

File tree

2 files changed

+98
-80
lines changed

2 files changed

+98
-80
lines changed

src/main/java/com/fishercoder/solutions/_220.java

Lines changed: 44 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -4,93 +4,57 @@
44

55
/**
66
* 220. Contains Duplicate III
7-
*
7+
* <p>
88
* Given an array of integers, find out whether there are two
99
* distinct indices i and j in the array such that the difference between nums[i] and nums[j] is at
1010
* most t and the difference between i and j is at most k.
1111
*/
1212
public class _220 {
13-
/**
14-
* TreeSet: per Java doc, is a NavigableSet implementation based on a TreeMap. The elements are ordered
15-
* using their natural ordering, or by a Comparator provided at set creation time, depending on
16-
* which constructor is used. This implementation provides guaranteed log(n) time cost for the
17-
* basic operations (add, remove and contains).
18-
*/
19-
20-
/**
21-
* TreeSet turns out to be a super handy data structure for this problem. It implements Set
22-
* interface and keeps elements in sorted order, plus it has two very handy APIs:
23-
*
24-
* https://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html#ceiling(E): Returns the
25-
* least element in this set greater than or equal to the given element, or null if there is no
26-
* such element.
27-
*
28-
* https://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html#floor(E): Returns the
29-
* greatest element in this set less than or equal to the given element, or null if there is no
30-
* such element.
31-
*
32-
* Idea: loop through this array, keep adding each element into the TreeSet, also keep an eye on
33-
* the size of the TreeSet, if it's greater than the required distance of k, then we remove the
34-
* left-most or oldest one from the set. For each element, we get the current floor and the
35-
* current ceiling and see if it works, if it does, then we return true immediately, otherwise,
36-
* we continue. Return false when we finished the loop.
37-
*/
3813

39-
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
40-
TreeSet<Integer> set = new TreeSet<Integer>();
41-
for (int i = 0; i < nums.length; i++) {
42-
Integer s = set.ceiling(nums[i]);//take the smallest greater number than nums[i] is there exists
43-
if (s != null && s - nums[i] <= t) {
44-
return true;//it must be s - nums[i] here, otherwise, cases like [4,2] 2, 1 wont' pass, because we'll get 2-4 = -2 which is a negative number that for sure will be smaller than t
45-
}
46-
Integer g = set.floor(nums[i]);//take the biggest smaller number than nums[i] if there exists
47-
if (g != null && (long) nums[i] - g <= t) {
48-
return true;
49-
}
50-
set.add(nums[i]);
51-
if (set.size() > k) {
52-
set.remove(nums[i - k]);//set doesn't have indices and it's not ordered, we could only specify the element
53-
//that we want to remove, this element is nums[i-k]
14+
public static class Solution1 {
15+
/**
16+
* TreeSet: per Java doc, is a NavigableSet implementation based on a TreeMap. The elements are ordered
17+
* using their natural ordering, or by a Comparator provided at set creation time, depending on
18+
* which constructor is used. This implementation provides guaranteed log(n) time cost for the
19+
* basic operations (add, remove and contains).
20+
*/
21+
22+
/**
23+
* TreeSet turns out to be a super handy data structure for this problem. It implements Set
24+
* interface and keeps elements in sorted order, plus it has two very handy APIs:
25+
* <p>
26+
* https://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html#ceiling(E): Returns the
27+
* least element in this set greater than or equal to the given element, or null if there is no
28+
* such element.
29+
* <p>
30+
* https://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html#floor(E): Returns the
31+
* greatest element in this set less than or equal to the given element, or null if there is no
32+
* such element.
33+
* <p>
34+
* Idea: loop through this array, keep adding each element into the TreeSet, also keep an eye on
35+
* the size of the TreeSet, if it's greater than the required distance of k, then we remove the
36+
* left-most or oldest one from the set. For each element, we get the current floor and the
37+
* current ceiling and see if it works, if it does, then we return true immediately, otherwise,
38+
* we continue. Return false when we finished the loop.
39+
*/
40+
41+
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
42+
TreeSet<Integer> set = new TreeSet<>();
43+
for (int i = 0; i < nums.length; ++i) {
44+
// Find the successor of current element
45+
Integer s = set.ceiling(nums[i]);
46+
if (s != null && s <= nums[i] + t) return true;
47+
48+
// Find the predecessor of current element
49+
Integer g = set.floor(nums[i]);
50+
if (g != null && nums[i] <= g + t) return true;
51+
52+
set.add(nums[i]);
53+
if (set.size() > k) {
54+
set.remove(nums[i - k]);
55+
}
5456
}
57+
return false;
5558
}
56-
return false;
57-
}
58-
59-
/**
60-
* converting to (long) is essential, otherwise cases like this:
61-
* <p>
62-
* [-1,2147483647]
63-
* <p>
64-
* 1
65-
* <p>
66-
* 2147483647
67-
* <p>
68-
* will overflow, i.e. Integer in Java is 32 bit which means Integer.MAX_VALUE =2147483647 and
69-
* Integer.MIN_VALUE = -2147483648, thus 2147483647 -(-1) = 2147483647+1 =-2147483648 instead of
70-
* 2147483648 (Java Integer won’t have this number), causing this test case to fail.
71-
*/
72-
73-
public static void main(String... strings) {
74-
_220 test = new _220();
75-
// int[] nums = new int[]{-1, -1};
76-
// int k = 1;
77-
// int t = 0;
78-
79-
// int[] nums = new int[] { 1, 2 };
80-
// int k = 0;
81-
// int t = 1;
82-
83-
int[] nums = new int[]{4, 2};
84-
int k = 2;
85-
int t = 1;
86-
87-
// int[] nums = new int[]{2, 2};
88-
// int k = 3;
89-
// int t = 0;
90-
91-
// int[] nums = new int[]{1};
92-
// int k = 1;
93-
// int t = 1;
94-
System.out.println(test.containsNearbyAlmostDuplicate(nums, k, t));
9559
}
9660
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.fishercoder;
2+
3+
import com.fishercoder.solutions._220;
4+
import org.junit.BeforeClass;
5+
import org.junit.Test;
6+
7+
import static org.junit.Assert.assertEquals;
8+
9+
public class _220Test {
10+
private static _220.Solution1 solution1;
11+
private static int[] nums;
12+
13+
@BeforeClass
14+
public static void setup() {
15+
solution1 = new _220.Solution1();
16+
}
17+
18+
@Test
19+
public void test1() {
20+
nums = new int[]{-1, -1};
21+
assertEquals(true, solution1.containsNearbyAlmostDuplicate(nums, 1, 0));
22+
}
23+
24+
@Test
25+
public void test2() {
26+
nums = new int[]{1, 2};
27+
assertEquals(false, solution1.containsNearbyAlmostDuplicate(nums, 0, 1));
28+
}
29+
30+
@Test
31+
public void test3() {
32+
nums = new int[]{4, 2};
33+
assertEquals(false, solution1.containsNearbyAlmostDuplicate(nums, 2, 1));
34+
}
35+
36+
@Test
37+
public void test4() {
38+
nums = new int[]{2, 2};
39+
assertEquals(true, solution1.containsNearbyAlmostDuplicate(nums, 3, 0));
40+
}
41+
42+
@Test
43+
public void test5() {
44+
nums = new int[]{1};
45+
assertEquals(false, solution1.containsNearbyAlmostDuplicate(nums, 1, 1));
46+
}
47+
48+
@Test
49+
public void test6() {
50+
nums = new int[]{2147483647, -2147483647};
51+
assertEquals(false, solution1.containsNearbyAlmostDuplicate(nums, 1, 2147483647));
52+
}
53+
54+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy