Skip to content

Commit addb081

Browse files
authored
Merge branch 'master' into add-title-case-v3
2 parents 1c8fcfe + bf8f3bd commit addb081

4 files changed

Lines changed: 182 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: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.thealgorithms.strings;
2+
3+
/**
4+
* Longest Common Substring finds the longest string that is a
5+
* contiguous substring of two input strings.
6+
* Example: "abcdef" and "zcdemf" -> "cde"
7+
*
8+
* @see <a href="https://en.wikipedia.org/wiki/Longest_common_substring">
9+
* Wikipedia: Longest Common Substring</a>
10+
*
11+
* author: Vraj Prajapati @Rosander0
12+
*/
13+
public final class LongestCommonSubstring {
14+
15+
private LongestCommonSubstring() {
16+
// Utility class
17+
}
18+
19+
/**
20+
* Finds the longest common substring of two strings.
21+
*
22+
* @param a First input string
23+
* @param b Second input string
24+
* @return The longest common substring, or empty string if none exists.
25+
* If multiple substrings share the maximum length, the first one found is returned.
26+
*/
27+
public static String longestCommonSubstring(final String a, final String b) {
28+
if (a == null || b == null || a.isEmpty() || b.isEmpty()) {
29+
return "";
30+
}
31+
32+
int[][] dp = new int[a.length() + 1][b.length() + 1];
33+
int maxLength = 0;
34+
int endIndex = 0;
35+
36+
for (int i = 1; i <= a.length(); i++) {
37+
for (int j = 1; j <= b.length(); j++) {
38+
if (a.charAt(i - 1) == b.charAt(j - 1)) {
39+
dp[i][j] = dp[i - 1][j - 1] + 1;
40+
if (dp[i][j] > maxLength) {
41+
maxLength = dp[i][j];
42+
endIndex = i;
43+
}
44+
} else {
45+
dp[i][j] = 0;
46+
}
47+
}
48+
}
49+
50+
if (maxLength == 0) {
51+
return "";
52+
}
53+
return a.substring(endIndex - maxLength, endIndex);
54+
}
55+
}
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+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.thealgorithms.strings;
2+
// author: Vraj Prajapati @Rosander0
3+
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
public class LongestCommonSubstringTest {
9+
10+
@Test
11+
public void testNullOrEmptyInputs() {
12+
assertEquals("", LongestCommonSubstring.longestCommonSubstring(null, "abc"));
13+
assertEquals("", LongestCommonSubstring.longestCommonSubstring("abc", null));
14+
assertEquals("", LongestCommonSubstring.longestCommonSubstring("", "abc"));
15+
assertEquals("", LongestCommonSubstring.longestCommonSubstring("abc", ""));
16+
}
17+
18+
@Test
19+
public void testNormalSubstrings() {
20+
assertEquals("cde", LongestCommonSubstring.longestCommonSubstring("abcdef", "zcdemf"));
21+
assertEquals("abc", LongestCommonSubstring.longestCommonSubstring("abc", "abc"));
22+
assertEquals("cdef", LongestCommonSubstring.longestCommonSubstring("abcdef", "cdefgh"));
23+
}
24+
25+
@Test
26+
public void testSingleCharacterAndNoMatch() {
27+
assertEquals("a", LongestCommonSubstring.longestCommonSubstring("a", "a"));
28+
assertEquals("", LongestCommonSubstring.longestCommonSubstring("abc", "xyz"));
29+
}
30+
31+
@Test
32+
public void testMultipleMatchesFirstLongest() {
33+
// Keeps the first matched longest substring when lengths are tied
34+
assertEquals("abc", LongestCommonSubstring.longestCommonSubstring("abcXdef", "abcYdef"));
35+
}
36+
}

0 commit comments

Comments
 (0)