Skip to content

Commit bf8f3bd

Browse files
feat: add count distinct elements in window algorithm (#7463)
* feat: add count distinct elements in window algorithm * feat: add CountDistinctElementsInWindow * fix: address CI issues
1 parent 0388455 commit bf8f3bd

2 files changed

Lines changed: 91 additions & 0 deletions

File tree

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.thealgorithms.slidingwindow;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
/**
7+
* Counts the number of distinct elements in every window of size k.
8+
*
9+
* @see <a href="https://www.geeksforgeeks.org/count-distinct-elements-in-every-window-of-size-k/">Reference</a>
10+
*/
11+
public final class CountDistinctElementsInWindow {
12+
13+
private CountDistinctElementsInWindow() {
14+
}
15+
16+
/**
17+
* Returns an array where each element is the count of distinct
18+
* elements in the corresponding window of size k.
19+
*
20+
* @param arr the input array
21+
* @param k the window size
22+
* @return array of distinct element counts per window
23+
*/
24+
public static int[] countDistinct(int[] arr, int k) {
25+
if (arr == null || arr.length == 0 || k <= 0 || k > arr.length) {
26+
throw new IllegalArgumentException("Invalid input");
27+
}
28+
29+
int n = arr.length;
30+
int[] result = new int[n - k + 1];
31+
Map<Integer, Integer> freqMap = new HashMap<>();
32+
33+
for (int i = 0; i < k; i++) {
34+
freqMap.merge(arr[i], 1, Integer::sum);
35+
}
36+
result[0] = freqMap.size();
37+
38+
for (int i = k; i < n; i++) {
39+
freqMap.merge(arr[i], 1, Integer::sum);
40+
41+
int outgoing = arr[i - k];
42+
43+
Integer count = freqMap.get(outgoing);
44+
if (count != null) {
45+
if (count == 1) {
46+
freqMap.remove(outgoing);
47+
} else {
48+
freqMap.put(outgoing, count - 1);
49+
}
50+
}
51+
52+
result[i - k + 1] = freqMap.size();
53+
}
54+
55+
return result;
56+
}
57+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.thealgorithms.slidingwindow;
2+
3+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
public class CountDistinctElementsInWindowTest {
9+
10+
@Test
11+
public void testBasicCase() {
12+
assertArrayEquals(new int[] {3, 2, 2}, CountDistinctElementsInWindow.countDistinct(new int[] {1, 2, 3, 2, 3}, 3));
13+
}
14+
15+
@Test
16+
public void testAllSame() {
17+
assertArrayEquals(new int[] {1, 1, 1}, CountDistinctElementsInWindow.countDistinct(new int[] {2, 2, 2, 2}, 2));
18+
}
19+
20+
@Test
21+
public void testAllDistinct() {
22+
assertArrayEquals(new int[] {3, 3}, CountDistinctElementsInWindow.countDistinct(new int[] {1, 2, 3, 4}, 3));
23+
}
24+
25+
@Test
26+
public void testWindowSizeEqualsArray() {
27+
assertArrayEquals(new int[] {4}, CountDistinctElementsInWindow.countDistinct(new int[] {1, 2, 3, 4}, 4));
28+
}
29+
30+
@Test
31+
public void testInvalidInput() {
32+
assertThrows(IllegalArgumentException.class, () -> CountDistinctElementsInWindow.countDistinct(new int[] {}, 2));
33+
}
34+
}

0 commit comments

Comments
 (0)