Skip to content

Commit f0b39dd

Browse files
authored
Merge branch 'master' into add-title-case-v3
2 parents 69e8eee + bf0ff70 commit f0b39dd

9 files changed

Lines changed: 348 additions & 1 deletion

File tree

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
<dependency>
113113
<groupId>com.puppycrawl.tools</groupId>
114114
<artifactId>checkstyle</artifactId>
115-
<version>13.5.0</version>
115+
<version>13.6.0</version>
116116
</dependency>
117117
</dependencies>
118118
</plugin>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.thealgorithms.maths;
2+
// author: Vraj Prajapati @Rosander0
3+
4+
/**
5+
* The Jacobsthal Sequence is a sequence of integers defined by the recurrence relation:
6+
* J(n) = J(n-1) + 2*J(n-2) with initial values J(0) = 0, J(1) = 1.
7+
* Example: 0, 1, 1, 3, 5, 11, 21, 43, 85, 171, 341...
8+
*
9+
* @see <a href="https://en.wikipedia.org/wiki/Jacobsthal_number">
10+
* Wikipedia: Jacobsthal Number</a>
11+
*/
12+
public final class JacobsthalNumber {
13+
14+
private JacobsthalNumber() {
15+
// Utility class
16+
}
17+
18+
/**
19+
* Calculates the nth term of the Jacobsthal Sequence.
20+
*
21+
* @param n the index of the sequence (must be non-negative)
22+
* @return the nth term of the Jacobsthal Sequence
23+
*/
24+
public static long jacobsthal(final int n) {
25+
if (n < 0) {
26+
throw new IllegalArgumentException("Input must be non-negative!");
27+
}
28+
if (n == 0) {
29+
return 0;
30+
}
31+
if (n == 1) {
32+
return 1;
33+
}
34+
long a = 0;
35+
long b = 1;
36+
long result = 0;
37+
for (int i = 2; i <= n; i++) {
38+
result = b + 2 * a;
39+
a = b;
40+
b = result;
41+
}
42+
return result;
43+
}
44+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.thealgorithms.maths;
2+
// author: Vraj Prajapati @Rosander0
3+
4+
/**
5+
* The Perrin Sequence is a sequence of integers defined by the recurrence relation:
6+
* P(n) = P(n-2) + P(n-3) with initial values P(0) = 3, P(1) = 0, P(2) = 2.
7+
* Example: 3, 0, 2, 3, 2, 5, 5, 7, 10, 12, 17, 22, 29, 39, 51...
8+
*
9+
* Note: The Perrin Sequence uses the same recurrence relation as the Padovan Sequence
10+
* but has different initial values.
11+
*
12+
* @see <a href="https://en.wikipedia.org/wiki/Perrin_number">
13+
* Wikipedia: Perrin Number</a>
14+
* @see PadovanSequence
15+
*/
16+
public final class PerrinNumber {
17+
18+
private PerrinNumber() {
19+
// Utility class
20+
}
21+
22+
/**
23+
* Calculates the nth term of the Perrin Sequence.
24+
*
25+
* @param n the index of the sequence (must be non-negative)
26+
* @return the nth term of the Perrin Sequence
27+
*/
28+
public static long perrin(final int n) {
29+
if (n < 0) {
30+
throw new IllegalArgumentException("Input must be non-negative!");
31+
}
32+
if (n == 0) {
33+
return 3;
34+
}
35+
if (n == 1) {
36+
return 0;
37+
}
38+
if (n == 2) {
39+
return 2;
40+
}
41+
long a = 3;
42+
long b = 0;
43+
long c = 2;
44+
long result = 0;
45+
for (int i = 3; i <= n; i++) {
46+
result = a + b;
47+
a = b;
48+
b = c;
49+
c = result;
50+
}
51+
return result;
52+
}
53+
}
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.maths;
2+
// author: Vraj Prajapati @Rosander0
3+
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
import static org.junit.jupiter.api.Assertions.assertThrows;
6+
7+
import org.junit.jupiter.api.Test;
8+
9+
public class JacobsthalNumberTest {
10+
11+
@Test
12+
public void testBaseCases() {
13+
assertEquals(0, JacobsthalNumber.jacobsthal(0));
14+
assertEquals(1, JacobsthalNumber.jacobsthal(1));
15+
}
16+
17+
@Test
18+
public void testKnownValues() {
19+
assertEquals(1, JacobsthalNumber.jacobsthal(2));
20+
assertEquals(3, JacobsthalNumber.jacobsthal(3));
21+
assertEquals(5, JacobsthalNumber.jacobsthal(4));
22+
assertEquals(11, JacobsthalNumber.jacobsthal(5));
23+
assertEquals(21, JacobsthalNumber.jacobsthal(6));
24+
assertEquals(43, JacobsthalNumber.jacobsthal(7));
25+
assertEquals(85, JacobsthalNumber.jacobsthal(8));
26+
assertEquals(171, JacobsthalNumber.jacobsthal(9));
27+
assertEquals(341, JacobsthalNumber.jacobsthal(10));
28+
}
29+
30+
@Test
31+
public void testInvalidInput() {
32+
assertThrows(IllegalArgumentException.class, () -> JacobsthalNumber.jacobsthal(-1));
33+
}
34+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.thealgorithms.maths;
2+
// author: Vraj Prajapati @Rosander0
3+
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
import static org.junit.jupiter.api.Assertions.assertThrows;
6+
7+
import org.junit.jupiter.api.Test;
8+
9+
public class PerrinNumberTest {
10+
11+
@Test
12+
public void testBaseCases() {
13+
assertEquals(3, PerrinNumber.perrin(0));
14+
assertEquals(0, PerrinNumber.perrin(1));
15+
assertEquals(2, PerrinNumber.perrin(2));
16+
}
17+
18+
@Test
19+
public void testKnownValues() {
20+
assertEquals(3, PerrinNumber.perrin(3));
21+
assertEquals(2, PerrinNumber.perrin(4));
22+
assertEquals(5, PerrinNumber.perrin(5));
23+
assertEquals(5, PerrinNumber.perrin(6));
24+
assertEquals(7, PerrinNumber.perrin(7));
25+
assertEquals(10, PerrinNumber.perrin(8));
26+
assertEquals(12, PerrinNumber.perrin(9));
27+
assertEquals(17, PerrinNumber.perrin(10));
28+
}
29+
30+
@Test
31+
public void testInvalidInput() {
32+
assertThrows(IllegalArgumentException.class, () -> PerrinNumber.perrin(-1));
33+
}
34+
}
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)