From 1a2aeddec3e2e429c9162aa511e586f452c0d09d Mon Sep 17 00:00:00 2001 From: likespro Date: Tue, 19 Nov 2024 09:09:06 +0200 Subject: [PATCH 001/146] Add optimized version of DijkstraAlgorithm (#6088) --- .../graphs/DijkstraOptimizedAlgorithm.java | 66 +++++++++++++++++++ .../DijkstraOptimizedAlgorithmTest.java | 64 ++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 src/main/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithm.java create mode 100644 src/test/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithmTest.java diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithm.java b/src/main/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithm.java new file mode 100644 index 000000000000..a686b808a970 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithm.java @@ -0,0 +1,66 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.Arrays; +import java.util.Set; +import java.util.TreeSet; +import org.apache.commons.lang3.tuple.Pair; + +/** + * Dijkstra's algorithm for finding the shortest path from a single source vertex to all other vertices in a graph. + */ +public class DijkstraOptimizedAlgorithm { + + private final int vertexCount; + + /** + * Constructs a Dijkstra object with the given number of vertices. + * + * @param vertexCount The number of vertices in the graph. + */ + public DijkstraOptimizedAlgorithm(int vertexCount) { + this.vertexCount = vertexCount; + } + + /** + * Executes Dijkstra's algorithm on the provided graph to find the shortest paths from the source vertex to all other vertices. + * + * The graph is represented as an adjacency matrix where {@code graph[i][j]} represents the weight of the edge from vertex {@code i} + * to vertex {@code j}. A value of 0 indicates no edge exists between the vertices. + * + * @param graph The graph represented as an adjacency matrix. + * @param source The source vertex. + * @return An array where the value at each index {@code i} represents the shortest distance from the source vertex to vertex {@code i}. + * @throws IllegalArgumentException if the source vertex is out of range. + */ + public int[] run(int[][] graph, int source) { + if (source < 0 || source >= vertexCount) { + throw new IllegalArgumentException("Incorrect source"); + } + + int[] distances = new int[vertexCount]; + boolean[] processed = new boolean[vertexCount]; + Set> unprocessed = new TreeSet<>(); + + Arrays.fill(distances, Integer.MAX_VALUE); + Arrays.fill(processed, false); + distances[source] = 0; + unprocessed.add(Pair.of(0, source)); + + while (!unprocessed.isEmpty()) { + Pair distanceAndU = unprocessed.iterator().next(); + unprocessed.remove(distanceAndU); + int u = distanceAndU.getRight(); + processed[u] = true; + + for (int v = 0; v < vertexCount; v++) { + if (!processed[v] && graph[u][v] != 0 && distances[u] != Integer.MAX_VALUE && distances[u] + graph[u][v] < distances[v]) { + unprocessed.remove(Pair.of(distances[v], v)); + distances[v] = distances[u] + graph[u][v]; + unprocessed.add(Pair.of(distances[v], v)); + } + } + } + + return distances; + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithmTest.java b/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithmTest.java new file mode 100644 index 000000000000..bf4e2828e069 --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithmTest.java @@ -0,0 +1,64 @@ +package com.thealgorithms.datastructures.graphs; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class DijkstraOptimizedAlgorithmTest { + + private DijkstraOptimizedAlgorithm dijkstraOptimizedAlgorithm; + private int[][] graph; + + @BeforeEach + void setUp() { + graph = new int[][] { + {0, 4, 0, 0, 0, 0, 0, 8, 0}, + {4, 0, 8, 0, 0, 0, 0, 11, 0}, + {0, 8, 0, 7, 0, 4, 0, 0, 2}, + {0, 0, 7, 0, 9, 14, 0, 0, 0}, + {0, 0, 0, 9, 0, 10, 0, 0, 0}, + {0, 0, 4, 14, 10, 0, 2, 0, 0}, + {0, 0, 0, 0, 0, 2, 0, 1, 6}, + {8, 11, 0, 0, 0, 0, 1, 0, 7}, + {0, 0, 2, 0, 0, 0, 6, 7, 0}, + }; + + dijkstraOptimizedAlgorithm = new DijkstraOptimizedAlgorithm(graph.length); + } + + @Test + void testRunAlgorithm() { + int[] expectedDistances = {0, 4, 12, 19, 21, 11, 9, 8, 14}; + assertArrayEquals(expectedDistances, dijkstraOptimizedAlgorithm.run(graph, 0)); + } + + @Test + void testGraphWithDisconnectedNodes() { + int[][] disconnectedGraph = { + {0, 3, 0, 0}, {3, 0, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0} // Node 3 is disconnected + }; + + DijkstraOptimizedAlgorithm dijkstraDisconnected = new DijkstraOptimizedAlgorithm(disconnectedGraph.length); + + // Testing from vertex 0 + int[] expectedDistances = {0, 3, 4, Integer.MAX_VALUE}; // Node 3 is unreachable + assertArrayEquals(expectedDistances, dijkstraDisconnected.run(disconnectedGraph, 0)); + } + + @Test + void testSingleVertexGraph() { + int[][] singleVertexGraph = {{0}}; + DijkstraOptimizedAlgorithm dijkstraSingleVertex = new DijkstraOptimizedAlgorithm(1); + + int[] expectedDistances = {0}; // The only vertex's distance to itself is 0 + assertArrayEquals(expectedDistances, dijkstraSingleVertex.run(singleVertexGraph, 0)); + } + + @Test + void testInvalidSourceVertex() { + assertThrows(IllegalArgumentException.class, () -> dijkstraOptimizedAlgorithm.run(graph, -1)); + assertThrows(IllegalArgumentException.class, () -> dijkstraOptimizedAlgorithm.run(graph, graph.length)); + } +} From 69870f8f55a98d1ae1cd6c8bd74763e6f0e197b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 23:57:33 +0100 Subject: [PATCH 002/146] Bump gitpod/workspace-java-21 from 2024-09-11-00-04-27 to 2024-11-26-08-43-19 (#6096) Bump gitpod/workspace-java-21 Bumps gitpod/workspace-java-21 from 2024-09-11-00-04-27 to 2024-11-26-08-43-19. --- updated-dependencies: - dependency-name: gitpod/workspace-java-21 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .gitpod.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile index f426f0921028..4b1885ffa388 100644 --- a/.gitpod.dockerfile +++ b/.gitpod.dockerfile @@ -1,4 +1,4 @@ -FROM gitpod/workspace-java-21:2024-09-11-00-04-27 +FROM gitpod/workspace-java-21:2024-11-26-08-43-19 ENV LLVM_SCRIPT="tmp_llvm.sh" From fff1826df28050629ad84e1c4ac54b029de57435 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 00:40:04 +0100 Subject: [PATCH 003/146] Bump com.puppycrawl.tools:checkstyle from 10.20.1 to 10.20.2 (#6097) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.20.1 to 10.20.2. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.20.1...checkstyle-10.20.2) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 402193e165ef..b0554afac2ad 100644 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,7 @@ com.puppycrawl.tools checkstyle - 10.20.1 + 10.20.2 From ebd7a3748c37798bb5d1b32e8ec79b3c9d712e55 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 23:31:33 +0100 Subject: [PATCH 004/146] Bump com.puppycrawl.tools:checkstyle from 10.20.2 to 10.21.0 (#6098) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.20.2 to 10.21.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.20.2...checkstyle-10.21.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b0554afac2ad..438e0bab33bd 100644 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,7 @@ com.puppycrawl.tools checkstyle - 10.20.2 + 10.21.0 From 9dfd99906139b4b04042c77cee0117f64d412a60 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 18:05:41 +0000 Subject: [PATCH 005/146] Bump org.junit:junit-bom from 5.11.3 to 5.11.4 (#6101) Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.11.3 to 5.11.4. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.3...r5.11.4) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 438e0bab33bd..78a49920fea9 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ org.junit junit-bom - 5.11.3 + 5.11.4 pom import From 2792c83bfb7364b0d0871aeeab793e5e6d9b9ebb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 18:09:39 +0000 Subject: [PATCH 006/146] Bump com.mebigfatguy.fb-contrib:fb-contrib from 7.6.8 to 7.6.9 (#6100) Bumps [com.mebigfatguy.fb-contrib:fb-contrib](https://github.com/mebigfatguy/fb-contrib) from 7.6.8 to 7.6.9. - [Commits](https://github.com/mebigfatguy/fb-contrib/commits) --- updated-dependencies: - dependency-name: com.mebigfatguy.fb-contrib:fb-contrib dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 78a49920fea9..6419fc640541 100644 --- a/pom.xml +++ b/pom.xml @@ -140,7 +140,7 @@ com.mebigfatguy.fb-contrib fb-contrib - 7.6.8 + 7.6.9 com.h3xstream.findsecbugs From 1e9cb9687d37316df445fa2fb12d7545c1606948 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 18:13:37 +0000 Subject: [PATCH 007/146] Bump org.junit.jupiter:junit-jupiter from 5.11.3 to 5.11.4 (#6103) Bumps [org.junit.jupiter:junit-jupiter](https://github.com/junit-team/junit5) from 5.11.3 to 5.11.4. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.3...r5.11.4) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6419fc640541..71c537a51f63 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ org.junit.jupiter junit-jupiter - 5.11.3 + 5.11.4 test From 13b5d6297e0fb24b001935969f745819e63d660e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 18:17:41 +0000 Subject: [PATCH 008/146] Bump org.junit.jupiter:junit-jupiter-api from 5.11.3 to 5.11.4 (#6102) Bumps [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit5) from 5.11.3 to 5.11.4. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.3...r5.11.4) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 71c537a51f63..48ad8a73be27 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ org.junit.jupiter junit-jupiter-api - 5.11.3 + 5.11.4 test From d65745816e7a6bf70e219bf217e8ab72dcf2c383 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 23:35:24 +0100 Subject: [PATCH 009/146] Bump org.assertj:assertj-core from 3.26.3 to 3.27.0 (#6106) Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.26.3 to 3.27.0. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.26.3...assertj-build-3.27.0) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 48ad8a73be27..ec5f4f2b1785 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 21 21 - 3.26.3 + 3.27.0 From d102fa77dc90172be6cf7eddd02af7ee3fb5da2a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 22:38:53 +0000 Subject: [PATCH 010/146] Bump org.apache.commons:commons-collections4 from 4.5.0-M2 to 4.5.0-M3 (#6107) Bumps org.apache.commons:commons-collections4 from 4.5.0-M2 to 4.5.0-M3. --- updated-dependencies: - dependency-name: org.apache.commons:commons-collections4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alex Klymenko --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ec5f4f2b1785..256a0ab296d8 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ org.apache.commons commons-collections4 - 4.5.0-M2 + 4.5.0-M3 From 2fff5790450c1b58a329d1ec576c6bc155b503ea Mon Sep 17 00:00:00 2001 From: Nguyen Tan Phat <52371943+nguyentanphat8694@users.noreply.github.com> Date: Sat, 21 Dec 2024 20:02:58 +0700 Subject: [PATCH 011/146] Add unit test for EditDistance (#6108) --- .../dynamicprogramming/EditDistanceTest.java | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/EditDistanceTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/EditDistanceTest.java index 267be9b056de..737e8d1d0918 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/EditDistanceTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/EditDistanceTest.java @@ -1,7 +1,9 @@ package com.thealgorithms.dynamicprogramming; +import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -12,4 +14,91 @@ public class EditDistanceTest { void testMinDistance(String str1, String str2, int expected) { assertEquals(expected, EditDistance.minDistance(str1, str2)); } + + @Test + public void testEditDistanceBothEmptyStrings() { + assertEquals(0, EditDistance.editDistance("", "")); + } + + @Test + public void testEditDistanceOneEmptyString() { + assertEquals(5, EditDistance.editDistance("", "hello")); + assertEquals(7, EditDistance.editDistance("worldly", "")); + } + + @Test + public void testEditDistanceOneEmptyStringMemoization() { + int[][] storage = new int[1][6]; + assertAll("String assertions", + () + -> assertEquals(5, EditDistance.editDistance("", "hello", storage)), + () -> assertEquals(0, storage[0][0]), () -> assertEquals(0, storage[0][1]), () -> assertEquals(0, storage[0][2]), () -> assertEquals(0, storage[0][3]), () -> assertEquals(0, storage[0][4]), () -> assertEquals(5, storage[0][5])); + } + + @Test + public void testEditDistanceEqualStrings() { + assertEquals(0, EditDistance.editDistance("test", "test")); + assertEquals(0, EditDistance.editDistance("abc", "abc")); + } + + @Test + public void testEditDistanceEqualStringsMemoization() { + int[][] storage = new int[4][4]; + assertAll("String assertions", + () + -> assertEquals(0, EditDistance.editDistance("abc", "abc", storage)), + () + -> assertEquals(0, storage[0][0]), + () + -> assertEquals(0, storage[0][1]), + () + -> assertEquals(0, storage[0][2]), + () + -> assertEquals(0, storage[0][3]), + () + -> assertEquals(0, storage[1][0]), + () + -> assertEquals(0, storage[1][1]), + () + -> assertEquals(0, storage[1][2]), + () + -> assertEquals(0, storage[1][3]), + () + -> assertEquals(0, storage[2][0]), + () -> assertEquals(0, storage[2][1]), () -> assertEquals(0, storage[2][2]), () -> assertEquals(0, storage[2][3]), () -> assertEquals(0, storage[3][0]), () -> assertEquals(0, storage[3][1]), () -> assertEquals(0, storage[3][2]), () -> assertEquals(0, storage[3][3])); + } + + @Test + public void testEditDistanceOneCharacterDifference() { + assertEquals(1, EditDistance.editDistance("cat", "bat")); + assertEquals(1, EditDistance.editDistance("cat", "cats")); + assertEquals(1, EditDistance.editDistance("cats", "cat")); + } + + @Test + public void testEditDistanceOneCharacterDifferenceMemoization() { + int[][] storage = new int[3][3]; + assertAll("All assertions", + () + -> assertEquals(1, EditDistance.editDistance("at", "it", storage)), + () + -> assertEquals(0, storage[0][0]), + () + -> assertEquals(1, storage[0][1]), + () -> assertEquals(2, storage[0][2]), () -> assertEquals(1, storage[1][0]), () -> assertEquals(0, storage[1][1]), () -> assertEquals(1, storage[1][2]), () -> assertEquals(2, storage[2][0]), () -> assertEquals(1, storage[2][1]), () -> assertEquals(1, storage[2][2])); + } + + @Test + public void testEditDistanceGeneralCases() { + assertEquals(3, EditDistance.editDistance("kitten", "sitting")); + assertEquals(2, EditDistance.editDistance("flaw", "lawn")); + assertEquals(5, EditDistance.editDistance("intention", "execution")); + } + + @Test + public void testEditDistanceGeneralCasesMemoization() { + int[][] storage = new int[7][8]; + assertEquals(3, EditDistance.editDistance("kitten", "sitting", storage)); + assertAll("All assertions", () -> assertEquals(0, storage[0][0]), () -> assertEquals(3, storage[6][7])); + } } From 6a60458398fb327e9f2a8d41c12ca884fc00ff17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 29 Dec 2024 19:59:25 +0000 Subject: [PATCH 012/146] Bump com.puppycrawl.tools:checkstyle from 10.21.0 to 10.21.1 (#6114) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.21.0 to 10.21.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.21.0...checkstyle-10.21.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 256a0ab296d8..142eb079b5ae 100644 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,7 @@ com.puppycrawl.tools checkstyle - 10.21.0 + 10.21.1 From 2da56d6ee4833068227fe92b637236620cf70bbb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 00:35:00 +0200 Subject: [PATCH 013/146] Bump org.assertj:assertj-core from 3.27.0 to 3.27.1 (#6115) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 142eb079b5ae..6535b4f39bf3 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 21 21 - 3.27.0 + 3.27.1 From 14db275c2b7abb0091587231bd823e8e00cbd32f Mon Sep 17 00:00:00 2001 From: Stanislav Belogolov Date: Wed, 1 Jan 2025 23:43:00 +0100 Subject: [PATCH 014/146] Improve Vampire Number (#6110) --- .../thealgorithms/maths/VampireNumber.java | 74 ++++++------------- .../maths/VampireNumberTest.java | 32 ++++++++ 2 files changed, 54 insertions(+), 52 deletions(-) create mode 100644 src/test/java/com/thealgorithms/maths/VampireNumberTest.java diff --git a/src/main/java/com/thealgorithms/maths/VampireNumber.java b/src/main/java/com/thealgorithms/maths/VampireNumber.java index 8820f8a23f70..45bb9a587778 100644 --- a/src/main/java/com/thealgorithms/maths/VampireNumber.java +++ b/src/main/java/com/thealgorithms/maths/VampireNumber.java @@ -1,78 +1,48 @@ package com.thealgorithms.maths; import java.util.ArrayList; -import java.util.Collections; /** - * n number theory, a vampire number (or true vampire number) is a composite + * In number theory, a vampire number (or true vampire number) is a composite * natural number with an even number of digits, that can be factored into two * natural numbers each with half as many digits as the original number and not * both with trailing zeroes, where the two factors contain precisely all the * digits of the original number, in any order, counting multiplicity. The first - * vampire number is 1260 = 21 × 60. * + * vampire number is 1260 = 21 × 60. * - *

- * link: https://en.wikipedia.org/wiki/Vampire_number * - * - *

+ * @see Vampire number on Wikipedia */ public final class VampireNumber { + // Forbid instantiation. private VampireNumber() { } - public static void main(String[] args) { - test(10, 1000); - } - - static void test(int startValue, int stopValue) { - int countofRes = 1; - StringBuilder res = new StringBuilder(); - - for (int i = startValue; i <= stopValue; i++) { - for (int j = i; j <= stopValue; j++) { - // System.out.println(i+ " "+ j); - if (isVampireNumber(i, j, true)) { - countofRes++; - res.append("").append(countofRes).append(": = ( ").append(i).append(",").append(j).append(" = ").append(i * j).append(")").append("\n"); - } - } - } - System.out.println(res); - } - - static boolean isVampireNumber(int a, int b, boolean noPseudoVamireNumbers) { - // this is for pseudoVampireNumbers pseudovampire number need not be of length n/2 digits - // for example 126 = 6 x 21 - if (noPseudoVamireNumbers) { - if (a * 10 <= b || b * 10 <= a) { - return false; - } + static boolean isVampireNumber(int a, int b, boolean ignorePseudoVampireNumbers) { + // Pseudo vampire numbers don't have to be of n/2 digits. E.g., 126 = 6 x 21 is such a number. + if (ignorePseudoVampireNumbers && String.valueOf(a).length() != String.valueOf(b).length()) { + return false; } - String mulDigits = splitIntoDigits(a * b, 0); - String faktorDigits = splitIntoDigits(a, b); + String mulDigits = splitIntoSortedDigits(a * b); + String factorDigits = splitIntoSortedDigits(a, b); - return mulDigits.equals(faktorDigits); + return mulDigits.equals(factorDigits); } - // methode to Split the numbers to Digits - static String splitIntoDigits(int num, int num2) { - StringBuilder res = new StringBuilder(); - + // Method to split a pair of numbers to digits and sort them in the ascending order. + static String splitIntoSortedDigits(int... nums) { + // Collect all digits in a list. ArrayList digits = new ArrayList<>(); - while (num > 0) { - digits.add(num % 10); - num /= 10; - } - while (num2 > 0) { - digits.add(num2 % 10); - num2 /= 10; - } - Collections.sort(digits); - for (int i : digits) { - res.append(i); + for (int num : nums) { + while (num > 0) { + digits.add(num % 10); + num /= 10; + } } + // Sort all digits and convert to String. + StringBuilder res = new StringBuilder(); + digits.stream().sorted().forEach(res::append); return res.toString(); } } diff --git a/src/test/java/com/thealgorithms/maths/VampireNumberTest.java b/src/test/java/com/thealgorithms/maths/VampireNumberTest.java new file mode 100644 index 000000000000..6f331f1252cd --- /dev/null +++ b/src/test/java/com/thealgorithms/maths/VampireNumberTest.java @@ -0,0 +1,32 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class VampireNumberTest { + @Test + void areVampireNumbers() { + Assertions.assertTrue(VampireNumber.isVampireNumber(15, 93, true)); + Assertions.assertTrue(VampireNumber.isVampireNumber(135, 801, true)); + Assertions.assertTrue(VampireNumber.isVampireNumber(201, 600, true)); + } + + @Test + void arePseudoVampireNumbers() { + Assertions.assertTrue(VampireNumber.isVampireNumber(150, 93, false)); + Assertions.assertTrue(VampireNumber.isVampireNumber(546, 84, false)); + Assertions.assertTrue(VampireNumber.isVampireNumber(641, 65, false)); + } + + @Test + void areNotVampireNumbers() { + Assertions.assertFalse(VampireNumber.isVampireNumber(51, 39, false)); + Assertions.assertFalse(VampireNumber.isVampireNumber(51, 39, true)); + } + + @Test + void testSplitIntoSortedDigits() { + Assertions.assertEquals("123", VampireNumber.splitIntoSortedDigits(321)); + Assertions.assertEquals("02234", VampireNumber.splitIntoSortedDigits(20, 324)); + } +} From 7c5351e11e620cb9d674140356c3aa0981838da6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 22:34:13 +0100 Subject: [PATCH 015/146] Bump org.mockito:mockito-core from 5.14.2 to 5.15.2 (#6116) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.14.2 to 5.15.2. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.14.2...v5.15.2) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6535b4f39bf3..b52e125a91e0 100644 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,7 @@ org.mockito mockito-core - 5.14.2 + 5.15.2 test From 5ab6356090c17cddd953c801eac4abb6ef48c9f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 21:34:03 +0000 Subject: [PATCH 016/146] Bump org.assertj:assertj-core from 3.27.1 to 3.27.2 (#6117) Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.27.1 to 3.27.2. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.1...assertj-build-3.27.2) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b52e125a91e0..3fc2c89d339f 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 21 21 - 3.27.1 + 3.27.2 From a9633c00007f3e2037d74f358ec917b142e3c630 Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Fri, 10 Jan 2025 19:50:09 +0100 Subject: [PATCH 017/146] style: include `ICAST_IDIV_CAST_TO_DOUBLE` (#6121) --- spotbugs-exclude.xml | 3 --- src/main/java/com/thealgorithms/maths/Average.java | 4 ++-- src/main/java/com/thealgorithms/others/KochSnowflake.java | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml index 14bc5dfe9439..11f89248018f 100644 --- a/spotbugs-exclude.xml +++ b/spotbugs-exclude.xml @@ -41,9 +41,6 @@ - - - diff --git a/src/main/java/com/thealgorithms/maths/Average.java b/src/main/java/com/thealgorithms/maths/Average.java index 6b9c20162da1..a550a7f6504d 100644 --- a/src/main/java/com/thealgorithms/maths/Average.java +++ b/src/main/java/com/thealgorithms/maths/Average.java @@ -37,7 +37,7 @@ public static double average(double[] numbers) { * @return the average of the given numbers * @throws IllegalArgumentException if the input array is {@code null} or empty */ - public static double average(int[] numbers) { + public static long average(int[] numbers) { if (numbers == null || numbers.length == 0) { throw new IllegalArgumentException("Numbers array cannot be empty or null"); } @@ -45,6 +45,6 @@ public static double average(int[] numbers) { for (int number : numbers) { sum += number; } - return (double) (sum / numbers.length); + return sum / numbers.length; } } diff --git a/src/main/java/com/thealgorithms/others/KochSnowflake.java b/src/main/java/com/thealgorithms/others/KochSnowflake.java index 46b8edb1f177..10986aabec4f 100644 --- a/src/main/java/com/thealgorithms/others/KochSnowflake.java +++ b/src/main/java/com/thealgorithms/others/KochSnowflake.java @@ -105,7 +105,7 @@ public static BufferedImage getKochSnowflake(int imageWidth, int steps) { double offsetX = imageWidth / 10.; double offsetY = imageWidth / 3.7; Vector2 vector1 = new Vector2(offsetX, offsetY); - Vector2 vector2 = new Vector2(imageWidth / 2, Math.sin(Math.PI / 3) * imageWidth * 0.8 + offsetY); + Vector2 vector2 = new Vector2(imageWidth / 2.0, Math.sin(Math.PI / 3.0) * imageWidth * 0.8 + offsetY); Vector2 vector3 = new Vector2(imageWidth - offsetX, offsetY); ArrayList initialVectors = new ArrayList(); initialVectors.add(vector1); From 1e6ed97fcf96d15556466e371096b0159ffe63af Mon Sep 17 00:00:00 2001 From: varada610 Date: Fri, 10 Jan 2025 23:17:40 -0800 Subject: [PATCH 018/146] Refactor files to be in correctly nested packages (#6120) --- pmd-exclude.properties | 1 - .../{misc => matrix}/InverseOfMatrix.java | 2 +- .../{misc => matrix}/MatrixTranspose.java | 2 +- .../{misc => matrix}/MedianOfMatrix.java | 2 +- .../{misc => matrix}/MirrorOfMatrix.java | 2 +- .../PrintAMatrixInSpiralOrder.java | 124 +++++++++--------- .../RotateMatrixBy90Degrees.java | 2 +- .../matrixexponentiation/Fibonacci.java | 6 +- .../{misc => matrix}/InverseOfMatrixTest.java | 3 +- .../{misc => matrix}/MatrixTransposeTest.java | 2 +- .../{misc => matrix}/MedianOfMatrixTest.java | 2 +- .../{misc => matrix}/MirrorOfMatrixTest.java | 2 +- .../TestPrintMatrixInSpiralOrder.java | 2 +- 13 files changed, 75 insertions(+), 77 deletions(-) rename src/main/java/com/thealgorithms/{misc => matrix}/InverseOfMatrix.java (98%) rename src/main/java/com/thealgorithms/{misc => matrix}/MatrixTranspose.java (97%) rename src/main/java/com/thealgorithms/{misc => matrix}/MedianOfMatrix.java (95%) rename src/main/java/com/thealgorithms/{misc => matrix}/MirrorOfMatrix.java (98%) rename src/main/java/com/thealgorithms/{others => matrix}/PrintAMatrixInSpiralOrder.java (94%) rename src/main/java/com/thealgorithms/{others => matrix}/RotateMatrixBy90Degrees.java (98%) rename src/main/java/com/thealgorithms/{ => matrix}/matrixexponentiation/Fibonacci.java (93%) rename src/test/java/com/thealgorithms/{misc => matrix}/InverseOfMatrixTest.java (96%) rename src/test/java/com/thealgorithms/{misc => matrix}/MatrixTransposeTest.java (98%) rename src/test/java/com/thealgorithms/{misc => matrix}/MedianOfMatrixTest.java (96%) rename src/test/java/com/thealgorithms/{misc => matrix}/MirrorOfMatrixTest.java (98%) rename src/test/java/com/thealgorithms/{others => matrix}/TestPrintMatrixInSpiralOrder.java (96%) diff --git a/pmd-exclude.properties b/pmd-exclude.properties index f6ee88196962..5bf31455e190 100644 --- a/pmd-exclude.properties +++ b/pmd-exclude.properties @@ -55,7 +55,6 @@ com.thealgorithms.maths.SumOfArithmeticSeries=UselessParentheses com.thealgorithms.maths.TrinomialTriangle=UselessParentheses com.thealgorithms.maths.VampireNumber=CollapsibleIfStatements com.thealgorithms.maths.Volume=UselessParentheses -com.thealgorithms.matrixexponentiation.Fibonacci=UnnecessaryFullyQualifiedName com.thealgorithms.misc.Sparsity=UselessParentheses com.thealgorithms.misc.ThreeSumProblem=UselessParentheses com.thealgorithms.misc.WordBoggle=UselessParentheses diff --git a/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java b/src/main/java/com/thealgorithms/matrix/InverseOfMatrix.java similarity index 98% rename from src/main/java/com/thealgorithms/misc/InverseOfMatrix.java rename to src/main/java/com/thealgorithms/matrix/InverseOfMatrix.java index 706feab0c69d..13e795a91297 100644 --- a/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java +++ b/src/main/java/com/thealgorithms/matrix/InverseOfMatrix.java @@ -1,4 +1,4 @@ -package com.thealgorithms.misc; +package com.thealgorithms.matrix; /** * This class provides methods to compute the inverse of a square matrix diff --git a/src/main/java/com/thealgorithms/misc/MatrixTranspose.java b/src/main/java/com/thealgorithms/matrix/MatrixTranspose.java similarity index 97% rename from src/main/java/com/thealgorithms/misc/MatrixTranspose.java rename to src/main/java/com/thealgorithms/matrix/MatrixTranspose.java index 743682780b01..f91ebc10b8a9 100644 --- a/src/main/java/com/thealgorithms/misc/MatrixTranspose.java +++ b/src/main/java/com/thealgorithms/matrix/MatrixTranspose.java @@ -1,4 +1,4 @@ -package com.thealgorithms.misc; +package com.thealgorithms.matrix; /** * diff --git a/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java b/src/main/java/com/thealgorithms/matrix/MedianOfMatrix.java similarity index 95% rename from src/main/java/com/thealgorithms/misc/MedianOfMatrix.java rename to src/main/java/com/thealgorithms/matrix/MedianOfMatrix.java index edeedbbee540..c710c60a2d2a 100644 --- a/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java +++ b/src/main/java/com/thealgorithms/matrix/MedianOfMatrix.java @@ -1,4 +1,4 @@ -package com.thealgorithms.misc; +package com.thealgorithms.matrix; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java b/src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java similarity index 98% rename from src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java rename to src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java index 89dfce3fe049..b24fcba75619 100644 --- a/src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java +++ b/src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java @@ -1,4 +1,4 @@ -package com.thealgorithms.misc; +package com.thealgorithms.matrix; // Problem Statement /* diff --git a/src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java b/src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java similarity index 94% rename from src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java rename to src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java index ddc37a916cbf..2e735222b7a6 100644 --- a/src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java +++ b/src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java @@ -1,62 +1,62 @@ -package com.thealgorithms.others; - -import java.util.ArrayList; -import java.util.List; - -public class PrintAMatrixInSpiralOrder { - /** - * Search a key in row and column wise sorted matrix - * - * @param matrix matrix to be searched - * @param row number of rows matrix has - * @param col number of columns matrix has - * @author Sadiul Hakim : https://github.com/sadiul-hakim - */ - - public List print(int[][] matrix, int row, int col) { - - // r traverses matrix row wise from first - int r = 0; - // c traverses matrix column wise from first - int c = 0; - int i; - - List result = new ArrayList<>(); - - while (r < row && c < col) { - // print first row of matrix - for (i = c; i < col; i++) { - result.add(matrix[r][i]); - } - - // increase r by one because first row printed - r++; - - // print last column - for (i = r; i < row; i++) { - result.add(matrix[i][col - 1]); - } - - // decrease col by one because last column has been printed - col--; - - // print rows from last except printed elements - if (r < row) { - for (i = col - 1; i >= c; i--) { - result.add(matrix[row - 1][i]); - } - - row--; - } - - // print columns from first except printed elements - if (c < col) { - for (i = row - 1; i >= r; i--) { - result.add(matrix[i][c]); - } - c++; - } - } - return result; - } -} +package com.thealgorithms.matrix; + +import java.util.ArrayList; +import java.util.List; + +public class PrintAMatrixInSpiralOrder { + /** + * Search a key in row and column wise sorted matrix + * + * @param matrix matrix to be searched + * @param row number of rows matrix has + * @param col number of columns matrix has + * @author Sadiul Hakim : https://github.com/sadiul-hakim + */ + + public List print(int[][] matrix, int row, int col) { + + // r traverses matrix row wise from first + int r = 0; + // c traverses matrix column wise from first + int c = 0; + int i; + + List result = new ArrayList<>(); + + while (r < row && c < col) { + // print first row of matrix + for (i = c; i < col; i++) { + result.add(matrix[r][i]); + } + + // increase r by one because first row printed + r++; + + // print last column + for (i = r; i < row; i++) { + result.add(matrix[i][col - 1]); + } + + // decrease col by one because last column has been printed + col--; + + // print rows from last except printed elements + if (r < row) { + for (i = col - 1; i >= c; i--) { + result.add(matrix[row - 1][i]); + } + + row--; + } + + // print columns from first except printed elements + if (c < col) { + for (i = row - 1; i >= r; i--) { + result.add(matrix[i][c]); + } + c++; + } + } + return result; + } +} diff --git a/src/main/java/com/thealgorithms/others/RotateMatrixBy90Degrees.java b/src/main/java/com/thealgorithms/matrix/RotateMatrixBy90Degrees.java similarity index 98% rename from src/main/java/com/thealgorithms/others/RotateMatrixBy90Degrees.java rename to src/main/java/com/thealgorithms/matrix/RotateMatrixBy90Degrees.java index 6ad0ef024342..9a7f255282ac 100644 --- a/src/main/java/com/thealgorithms/others/RotateMatrixBy90Degrees.java +++ b/src/main/java/com/thealgorithms/matrix/RotateMatrixBy90Degrees.java @@ -1,4 +1,4 @@ -package com.thealgorithms.others; +package com.thealgorithms.matrix; import java.util.Scanner; /** diff --git a/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java b/src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java similarity index 93% rename from src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java rename to src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java index afd34933047a..9c9f97b93ea4 100644 --- a/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java +++ b/src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java @@ -1,4 +1,4 @@ -package com.thealgorithms.matrixexponentiation; +package com.thealgorithms.matrix.matrixexponentiation; import java.util.Scanner; @@ -55,14 +55,14 @@ private static int[][] matrixMultiplication(int[][] matrix1, int[][] matrix2) { */ public static int[][] fib(int n) { if (n == 0) { - return Fibonacci.IDENTITY_MATRIX; + return IDENTITY_MATRIX; } else { int[][] cachedResult = fib(n / 2); int[][] matrixExpResult = matrixMultiplication(cachedResult, cachedResult); if (n % 2 == 0) { return matrixExpResult; } else { - return matrixMultiplication(Fibonacci.FIB_MATRIX, matrixExpResult); + return matrixMultiplication(FIB_MATRIX, matrixExpResult); } } } diff --git a/src/test/java/com/thealgorithms/misc/InverseOfMatrixTest.java b/src/test/java/com/thealgorithms/matrix/InverseOfMatrixTest.java similarity index 96% rename from src/test/java/com/thealgorithms/misc/InverseOfMatrixTest.java rename to src/test/java/com/thealgorithms/matrix/InverseOfMatrixTest.java index 2f20de444315..930fb377cd32 100644 --- a/src/test/java/com/thealgorithms/misc/InverseOfMatrixTest.java +++ b/src/test/java/com/thealgorithms/matrix/InverseOfMatrixTest.java @@ -1,5 +1,4 @@ -package com.thealgorithms.misc; - +package com.thealgorithms.matrix; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import java.util.stream.Stream; diff --git a/src/test/java/com/thealgorithms/misc/MatrixTransposeTest.java b/src/test/java/com/thealgorithms/matrix/MatrixTransposeTest.java similarity index 98% rename from src/test/java/com/thealgorithms/misc/MatrixTransposeTest.java rename to src/test/java/com/thealgorithms/matrix/MatrixTransposeTest.java index cf668807b819..0457f31418cf 100644 --- a/src/test/java/com/thealgorithms/misc/MatrixTransposeTest.java +++ b/src/test/java/com/thealgorithms/matrix/MatrixTransposeTest.java @@ -1,4 +1,4 @@ -package com.thealgorithms.misc; +package com.thealgorithms.matrix; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/src/test/java/com/thealgorithms/misc/MedianOfMatrixTest.java b/src/test/java/com/thealgorithms/matrix/MedianOfMatrixTest.java similarity index 96% rename from src/test/java/com/thealgorithms/misc/MedianOfMatrixTest.java rename to src/test/java/com/thealgorithms/matrix/MedianOfMatrixTest.java index 19bc66857ae6..db66bb2d187b 100644 --- a/src/test/java/com/thealgorithms/misc/MedianOfMatrixTest.java +++ b/src/test/java/com/thealgorithms/matrix/MedianOfMatrixTest.java @@ -1,4 +1,4 @@ -package com.thealgorithms.misc; +package com.thealgorithms.matrix; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java b/src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java similarity index 98% rename from src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java rename to src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java index 0da0cf0f804a..2d68e1faaa17 100644 --- a/src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java +++ b/src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java @@ -1,4 +1,4 @@ -package com.thealgorithms.misc; +package com.thealgorithms.matrix; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertNull; diff --git a/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java b/src/test/java/com/thealgorithms/matrix/TestPrintMatrixInSpiralOrder.java similarity index 96% rename from src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java rename to src/test/java/com/thealgorithms/matrix/TestPrintMatrixInSpiralOrder.java index 986e72ea45b5..bb415a5861a8 100644 --- a/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java +++ b/src/test/java/com/thealgorithms/matrix/TestPrintMatrixInSpiralOrder.java @@ -1,4 +1,4 @@ -package com.thealgorithms.others; +package com.thealgorithms.matrix; import static org.junit.jupiter.api.Assertions.assertIterableEquals; From 08c0f4ac2ddfa48e1a00e2dd9c7a350ecb7d4d23 Mon Sep 17 00:00:00 2001 From: Rully Date: Sun, 12 Jan 2025 18:13:01 +0700 Subject: [PATCH 019/146] improve zig-zag-pattern (#6128) --- .../strings/zigZagPattern/ZigZagPattern.java | 49 +++++++++---------- .../zigZagPattern/ZigZagPatternTest.java | 6 ++- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/thealgorithms/strings/zigZagPattern/ZigZagPattern.java b/src/main/java/com/thealgorithms/strings/zigZagPattern/ZigZagPattern.java index 3f33fc17b9b0..ad7835bdbb97 100644 --- a/src/main/java/com/thealgorithms/strings/zigZagPattern/ZigZagPattern.java +++ b/src/main/java/com/thealgorithms/strings/zigZagPattern/ZigZagPattern.java @@ -1,41 +1,38 @@ package com.thealgorithms.strings.zigZagPattern; final class ZigZagPattern { + private ZigZagPattern() { } + /** + * Encodes a given string into a zig-zag pattern. + * + * @param s the input string to be encoded + * @param numRows the number of rows in the zigzag pattern + * @return the encoded string in zigzag pattern format + */ public static String encode(String s, int numRows) { if (numRows < 2 || s.length() < numRows) { return s; } - int start = 0; - int index = 0; - int height = 1; - int depth = numRows; - char[] zigZagedArray = new char[s.length()]; - while (depth != 0) { - int pointer = start; - int heightSpace = 2 + ((height - 2) * 2); - int depthSpace = 2 + ((depth - 2) * 2); - boolean bool = true; - while (pointer < s.length()) { - zigZagedArray[index++] = s.charAt(pointer); - if (heightSpace == 0) { - pointer += depthSpace; - } else if (depthSpace == 0) { - pointer += heightSpace; - } else if (bool) { - pointer += depthSpace; - bool = false; - } else { - pointer += heightSpace; - bool = true; + + StringBuilder result = new StringBuilder(s.length()); + int cycleLength = 2 * numRows - 2; + + for (int row = 0; row < numRows; row++) { + for (int j = row; j < s.length(); j += cycleLength) { + result.append(s.charAt(j)); + + if (row > 0 && row < numRows - 1) { + int diagonal = j + cycleLength - 2 * row; + if (diagonal < s.length()) { + result.append(s.charAt(diagonal)); + } } } - height++; - depth--; - start++; } - return new String(zigZagedArray); + + return result.toString(); } } diff --git a/src/test/java/com/thealgorithms/strings/zigZagPattern/ZigZagPatternTest.java b/src/test/java/com/thealgorithms/strings/zigZagPattern/ZigZagPatternTest.java index 518bfab80f08..2cbbfe3d2dd8 100644 --- a/src/test/java/com/thealgorithms/strings/zigZagPattern/ZigZagPatternTest.java +++ b/src/test/java/com/thealgorithms/strings/zigZagPattern/ZigZagPatternTest.java @@ -6,10 +6,14 @@ public class ZigZagPatternTest { @Test - public void palindrome() { + public void testZigZagPattern() { String input1 = "HelloWorldFromJava"; String input2 = "javaIsAProgrammingLanguage"; Assertions.assertEquals(ZigZagPattern.encode(input1, 4), "HooeWrrmalolFJvlda"); Assertions.assertEquals(ZigZagPattern.encode(input2, 4), "jAaLgasPrmgaaevIrgmnnuaoig"); + // Edge cases + Assertions.assertEquals("ABC", ZigZagPattern.encode("ABC", 1)); // Single row + Assertions.assertEquals("A", ZigZagPattern.encode("A", 2)); // numRows > length of string + Assertions.assertEquals("", ZigZagPattern.encode("", 3)); // Empty string } } From bd785dea4dadc2b2967d174cf3afebe88a699fb8 Mon Sep 17 00:00:00 2001 From: "p@ren" <83308376+paren-thesis@users.noreply.github.com> Date: Sun, 12 Jan 2025 11:29:27 +0000 Subject: [PATCH 020/146] Refactor and enhance the 'Upper' class (#6118) --- .../java/com/thealgorithms/strings/Upper.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/thealgorithms/strings/Upper.java b/src/main/java/com/thealgorithms/strings/Upper.java index fa9a408416ea..5e248cb6ee39 100644 --- a/src/main/java/com/thealgorithms/strings/Upper.java +++ b/src/main/java/com/thealgorithms/strings/Upper.java @@ -21,15 +21,19 @@ public static void main(String[] args) { * @return the {@code String}, converted to uppercase. */ public static String toUpperCase(String s) { - if (s == null || s.isEmpty()) { + if (s == null) { + throw new IllegalArgumentException("Input string connot be null"); + } + if (s.isEmpty()) { return s; } - char[] values = s.toCharArray(); - for (int i = 0; i < values.length; ++i) { - if (Character.isLetter(values[i]) && Character.isLowerCase(values[i])) { - values[i] = Character.toUpperCase(values[i]); + StringBuilder result = new StringBuilder(s); + for (int i = 0; i < result.length(); ++i) { + char currentChar = result.charAt(i); + if (Character.isLetter(currentChar) && Character.isLowerCase(currentChar)) { + result.setCharAt(i, Character.toUpperCase(currentChar)); } } - return new String(values); + return result.toString(); } } From 779381f902821ea8fa8dc641b01d513e1a050b99 Mon Sep 17 00:00:00 2001 From: Patient_Pace_Coder <104113247+Patient-Pace-Coder@users.noreply.github.com> Date: Mon, 13 Jan 2025 13:34:08 +0530 Subject: [PATCH 021/146] Update Armstrong (#6131) --- src/main/java/com/thealgorithms/maths/Armstrong.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/Armstrong.java b/src/main/java/com/thealgorithms/maths/Armstrong.java index ff4ae027a0b7..9a7a014ec99f 100644 --- a/src/main/java/com/thealgorithms/maths/Armstrong.java +++ b/src/main/java/com/thealgorithms/maths/Armstrong.java @@ -10,6 +10,7 @@ * An Armstrong number is often called a Narcissistic number. * * @author satyabarghav + * @modifier rahul katteda - (13/01/2025) - [updated the logic for getting total number of digits] */ public class Armstrong { @@ -20,14 +21,16 @@ public class Armstrong { * @return {@code true} if the given number is an Armstrong number, {@code false} otherwise */ public boolean isArmstrong(int number) { + if (number < 0) { + return false; // Negative numbers cannot be Armstrong numbers + } long sum = 0; - String temp = Integer.toString(number); // Convert the given number to a string - int power = temp.length(); // Extract the length of the number (number of digits) + int totalDigits = (int) Math.log10(number) + 1; // get the length of the number (number of digits) long originalNumber = number; while (originalNumber > 0) { long digit = originalNumber % 10; - sum += (long) Math.pow(digit, power); // The digit raised to the power of the number of digits and added to the sum. + sum += (long) Math.pow(digit, totalDigits); // The digit raised to the power of total number of digits and added to the sum. originalNumber /= 10; } From 39122a9ac79d4c7094c6741293780bb804d7623f Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:56:43 +0100 Subject: [PATCH 022/146] style: include `PCOA_PARTIALLY_CONSTRUCTED_OBJECT_ACCESS` (#6133) --- spotbugs-exclude.xml | 3 -- .../scheduling/SJFScheduling.java | 28 +++++++++---------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml index 11f89248018f..d3eff458ea45 100644 --- a/spotbugs-exclude.xml +++ b/spotbugs-exclude.xml @@ -114,9 +114,6 @@ - - - diff --git a/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java b/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java index 6d105003e68f..cbbc65a3afc5 100644 --- a/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java +++ b/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java @@ -14,6 +14,18 @@ public class SJFScheduling { protected ArrayList processes; protected ArrayList schedule; + private static void sortProcessesByArrivalTime(List processes) { + for (int i = 0; i < processes.size(); i++) { + for (int j = i + 1; j < processes.size() - 1; j++) { + if (processes.get(j).getArrivalTime() > processes.get(j + 1).getArrivalTime()) { + final var temp = processes.get(j); + processes.set(j, processes.get(j + 1)); + processes.set(j + 1, temp); + } + } + } + } + /** * a simple constructor * @param processes a list of processes the user wants to schedule @@ -22,22 +34,10 @@ public class SJFScheduling { SJFScheduling(final ArrayList processes) { this.processes = processes; schedule = new ArrayList<>(); - sortByArrivalTime(); + sortProcessesByArrivalTime(this.processes); } protected void sortByArrivalTime() { - int size = processes.size(); - int i; - int j; - ProcessDetails temp; - for (i = 0; i < size; i++) { - for (j = i + 1; j < size - 1; j++) { - if (processes.get(j).getArrivalTime() > processes.get(j + 1).getArrivalTime()) { - temp = processes.get(j); - processes.set(j, processes.get(j + 1)); - processes.set(j + 1, temp); - } - } - } + sortProcessesByArrivalTime(processes); } /** From 754bf6c5f8f55b758bdee2667f6cadf4f0ab659f Mon Sep 17 00:00:00 2001 From: BILLSARAN <121570181+BILLSARAN@users.noreply.github.com> Date: Mon, 13 Jan 2025 23:37:58 +0200 Subject: [PATCH 023/146] Add Goldbach's Conjecture algorithm (#6127) --- .../maths/GoldbachConjecture.java | 30 +++++++++++++++++++ .../maths/GoldbachConjectureTest.java | 29 ++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/main/java/com/thealgorithms/maths/GoldbachConjecture.java create mode 100644 src/test/java/com/thealgorithms/maths/GoldbachConjectureTest.java diff --git a/src/main/java/com/thealgorithms/maths/GoldbachConjecture.java b/src/main/java/com/thealgorithms/maths/GoldbachConjecture.java new file mode 100644 index 000000000000..52391bc100d8 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/GoldbachConjecture.java @@ -0,0 +1,30 @@ +package com.thealgorithms.maths; + +import static com.thealgorithms.maths.PrimeCheck.isPrime; + +/** + * This is a representation of the unsolved problem of Goldbach's Projection, according to which every + * even natural number greater than 2 can be written as the sum of 2 prime numbers + * More info: https://en.wikipedia.org/wiki/Goldbach%27s_conjecture + * @author Vasilis Sarantidis (https://github.com/BILLSARAN) + */ + +public final class GoldbachConjecture { + private GoldbachConjecture() { + } + public record Result(int number1, int number2) { + } + + public static Result getPrimeSum(int number) { + if (number <= 2 || number % 2 != 0) { + throw new IllegalArgumentException("Number must be even and greater than 2."); + } + + for (int i = 0; i <= number / 2; i++) { + if (isPrime(i) && isPrime(number - i)) { + return new Result(i, number - i); + } + } + throw new IllegalStateException("No valid prime sum found."); // Should not occur + } +} diff --git a/src/test/java/com/thealgorithms/maths/GoldbachConjectureTest.java b/src/test/java/com/thealgorithms/maths/GoldbachConjectureTest.java new file mode 100644 index 000000000000..84c5824d26ae --- /dev/null +++ b/src/test/java/com/thealgorithms/maths/GoldbachConjectureTest.java @@ -0,0 +1,29 @@ +package com.thealgorithms.maths; + +import static com.thealgorithms.maths.GoldbachConjecture.getPrimeSum; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class GoldbachConjectureTest { + @Test + void testValidEvenNumbers() { + assertEquals(new GoldbachConjecture.Result(3, 7), getPrimeSum(10)); // 10 = 3 + 7 + assertEquals(new GoldbachConjecture.Result(5, 7), getPrimeSum(12)); // 12 = 5 + 7 + assertEquals(new GoldbachConjecture.Result(3, 11), getPrimeSum(14)); // 14 = 3 + 11 + assertEquals(new GoldbachConjecture.Result(5, 13), getPrimeSum(18)); // 18 = 5 + 13 + } + @Test + void testInvalidOddNumbers() { + assertThrows(IllegalArgumentException.class, () -> getPrimeSum(7)); + assertThrows(IllegalArgumentException.class, () -> getPrimeSum(15)); + } + @Test + void testLesserThanTwo() { + assertThrows(IllegalArgumentException.class, () -> getPrimeSum(1)); + assertThrows(IllegalArgumentException.class, () -> getPrimeSum(2)); + assertThrows(IllegalArgumentException.class, () -> getPrimeSum(-5)); + assertThrows(IllegalArgumentException.class, () -> getPrimeSum(-26)); + } +} From 466ff0b4c27437993994909b229300111ef357be Mon Sep 17 00:00:00 2001 From: Prathamesh Zingade <101877850+ZingadePrathamesh@users.noreply.github.com> Date: Thu, 16 Jan 2025 13:16:57 +0530 Subject: [PATCH 024/146] Add convertion of numbers into their word representation (#6137) --- DIRECTORY.md | 48 +++++---- .../conversions/NumberToWords.java | 100 ++++++++++++++++++ .../conversions/NumberToWordsTest.java | 60 +++++++++++ 3 files changed, 190 insertions(+), 18 deletions(-) create mode 100644 src/main/java/com/thealgorithms/conversions/NumberToWords.java create mode 100644 src/test/java/com/thealgorithms/conversions/NumberToWordsTest.java diff --git a/DIRECTORY.md b/DIRECTORY.md index 01e031b58581..4fa1392a3c17 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -5,6 +5,7 @@ * com * thealgorithms * audiofilters + * [EMAFilter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/audiofilters/EMAFilter.java) * [IIRFilter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java) * backtracking * [AllPathsFromSourceToTarget](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java) @@ -107,6 +108,7 @@ * [IPConverter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/IPConverter.java) * [IPv6Converter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/IPv6Converter.java) * [MorseCodeConverter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/MorseCodeConverter.java) + * [NumberToWords](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/NumberToWords.java) * [OctalToBinary](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/OctalToBinary.java) * [OctalToDecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java) * [OctalToHexadecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java) @@ -147,6 +149,7 @@ * [ConnectedComponent](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java) * [Cycles](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java) * [DijkstraAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithm.java) + * [DijkstraOptimizedAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithm.java) * [EdmondsBlossomAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithm.java) * [FloydWarshall](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java) * [FordFulkerson](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/FordFulkerson.java) @@ -404,6 +407,7 @@ * [GCD](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/GCD.java) * [GCDRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/GCDRecursion.java) * [GenericRoot](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/GenericRoot.java) + * [GoldbachConjecture](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/GoldbachConjecture.java) * [HarshadNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/HarshadNumber.java) * [HeronsFormula](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/HeronsFormula.java) * [JosephusProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/JosephusProblem.java) @@ -470,21 +474,24 @@ * [VampireNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/VampireNumber.java) * [VectorCrossProduct](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/VectorCrossProduct.java) * [Volume](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Volume.java) - * matrixexponentiation - * [Fibonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java) + * matrix + * [InverseOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/InverseOfMatrix.java) + * matrixexponentiation + * [Fibonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java) + * [MatrixTranspose](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/MatrixTranspose.java) + * [MedianOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/MedianOfMatrix.java) + * [MirrorOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java) + * [PrintAMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java) + * [RotateMatrixBy90Degrees](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/RotateMatrixBy90Degrees.java) * misc * [ColorContrastRatio](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java) - * [InverseOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java) * [MapReduce](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MapReduce.java) - * [MatrixTranspose](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MatrixTranspose.java) - * [MedianOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java) * [MedianOfRunningArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java) * [MedianOfRunningArrayByte](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java) * [MedianOfRunningArrayDouble](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java) * [MedianOfRunningArrayFloat](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java) * [MedianOfRunningArrayInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java) * [MedianOfRunningArrayLong](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java) - * [MirrorOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java) * [PalindromePrime](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/PalindromePrime.java) * [PalindromeSinglyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java) * [RangeInSortedArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java) @@ -508,7 +515,6 @@ * [CRCAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/CRCAlgorithm.java) * [Damm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Damm.java) * [Dijkstra](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Dijkstra.java) - * [FibbonaciSeries](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/FibbonaciSeries.java) * [FloydTriangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/FloydTriangle.java) * [GaussLegendre](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/GaussLegendre.java) * [HappyNumbersSeq](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/HappyNumbersSeq.java) @@ -529,18 +535,17 @@ * [PageRank](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PageRank.java) * [PasswordGen](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PasswordGen.java) * [PerlinNoise](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PerlinNoise.java) - * [PrintAMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java) * [QueueUsingTwoStacks](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java) * [RemoveDuplicateFromString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/RemoveDuplicateFromString.java) * [ReverseStackUsingRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java) - * [RotateMatrixBy90Degrees](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/RotateMatrixBy90Degrees.java) * [SkylineProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/SkylineProblem.java) * [Sudoku](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Sudoku.java) * [TowerOfHanoi](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/TowerOfHanoi.java) * [TwoPointers](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/TwoPointers.java) * [Verhoeff](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Verhoeff.java) - * Recursion - * [GenerateSubsets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/Recursion/GenerateSubsets.java) + * recursion + * [FibonacciSeries](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/recursion/FibonacciSeries.java) + * [GenerateSubsets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/recursion/GenerateSubsets.java) * scheduling * [AgingScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/AgingScheduling.java) * diskscheduling @@ -718,6 +723,7 @@ * com * thealgorithms * audiofilters + * [EMAFilterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/audiofilters/EMAFilterTest.java) * [IIRFilterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/audiofilters/IIRFilterTest.java) * backtracking * [AllPathsFromSourceToTargetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java) @@ -814,6 +820,7 @@ * [IPConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/IPConverterTest.java) * [IPv6ConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/IPv6ConverterTest.java) * [MorseCodeConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/MorseCodeConverterTest.java) + * [NumberToWordsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/NumberToWordsTest.java) * [OctalToBinaryTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java) * [OctalToDecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java) * [OctalToHexadecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/OctalToHexadecimalTest.java) @@ -849,6 +856,7 @@ * [BipartiteGraphDFSTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java) * [BoruvkaAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java) * [DijkstraAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java) + * [DijkstraOptimizedAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithmTest.java) * [EdmondsBlossomAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithmTest.java) * [FloydWarshallTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/FloydWarshallTest.java) * [FordFulkersonTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/FordFulkersonTest.java) @@ -1070,6 +1078,7 @@ * [GCDRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GCDRecursionTest.java) * [GCDTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GCDTest.java) * [GenericRootTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GenericRootTest.java) + * [GoldbachConjectureTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GoldbachConjectureTest.java) * [HarshadNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/HarshadNumberTest.java) * [HeronsFormulaTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java) * [JosephusProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/JosephusProblemTest.java) @@ -1126,15 +1135,18 @@ * [TestArmstrong](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/TestArmstrong.java) * [TwinPrimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/TwinPrimeTest.java) * [UniformNumbersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/UniformNumbersTest.java) + * [VampireNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/VampireNumberTest.java) * [VolumeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/VolumeTest.java) + * matrix + * [InverseOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/InverseOfMatrixTest.java) + * [MatrixTransposeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MatrixTransposeTest.java) + * [MedianOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MedianOfMatrixTest.java) + * [MirrorOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java) + * [TestPrintMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/TestPrintMatrixInSpiralOrder.java) * misc * [ColorContrastRatioTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/ColorContrastRatioTest.java) - * [InverseOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/InverseOfMatrixTest.java) * [MapReduceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MapReduceTest.java) - * [MatrixTransposeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MatrixTransposeTest.java) - * [MedianOfMatrixtest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java) * [MedianOfRunningArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java) - * [MirrorOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java) * [PalindromePrimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/PalindromePrimeTest.java) * [PalindromeSinglyLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/PalindromeSinglyLinkedListTest.java) * [RangeInSortedArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/RangeInSortedArrayTest.java) @@ -1171,12 +1183,12 @@ * [ReverseStackUsingRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ReverseStackUsingRecursionTest.java) * [SkylineProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/SkylineProblemTest.java) * [SudokuTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/SudokuTest.java) - * [TestPrintMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java) * [TowerOfHanoiTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TowerOfHanoiTest.java) * [TwoPointersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TwoPointersTest.java) * [WorstFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java) - * Recursion - * [GenerateSubsetsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/Recursion/GenerateSubsetsTest.java) + * recursion + * [FibonacciSeriesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/recursion/FibonacciSeriesTest.java) + * [GenerateSubsetsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/recursion/GenerateSubsetsTest.java) * scheduling * [AgingSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/AgingSchedulingTest.java) * diskscheduling diff --git a/src/main/java/com/thealgorithms/conversions/NumberToWords.java b/src/main/java/com/thealgorithms/conversions/NumberToWords.java new file mode 100644 index 000000000000..e39c5b2dea86 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/NumberToWords.java @@ -0,0 +1,100 @@ +package com.thealgorithms.conversions; + +import java.math.BigDecimal; + +/** + A Java-based utility for converting numeric values into their English word + representations. Whether you need to convert a small number, a large number + with millions and billions, or even a number with decimal places, this utility + has you covered. + * + */ +public final class NumberToWords { + + private NumberToWords() { + } + + private static final String[] UNITS = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}; + + private static final String[] TENS = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}; + + private static final String[] POWERS = {"", "Thousand", "Million", "Billion", "Trillion"}; + + private static final String ZERO = "Zero"; + private static final String POINT = " Point"; + private static final String NEGATIVE = "Negative "; + + public static String convert(BigDecimal number) { + if (number == null) { + return "Invalid Input"; + } + + // Check for negative sign + boolean isNegative = number.signum() < 0; + + // Split the number into whole and fractional parts + BigDecimal[] parts = number.abs().divideAndRemainder(BigDecimal.ONE); + BigDecimal wholePart = parts[0]; // Keep whole part as BigDecimal + String fractionalPartStr = parts[1].compareTo(BigDecimal.ZERO) > 0 ? parts[1].toPlainString().substring(2) : ""; // Get fractional part only if it exists + + // Convert whole part to words + StringBuilder result = new StringBuilder(); + if (isNegative) { + result.append(NEGATIVE); + } + result.append(convertWholeNumberToWords(wholePart)); + + // Convert fractional part to words + if (!fractionalPartStr.isEmpty()) { + result.append(POINT); + for (char digit : fractionalPartStr.toCharArray()) { + int digitValue = Character.getNumericValue(digit); + result.append(" ").append(digitValue == 0 ? ZERO : UNITS[digitValue]); + } + } + + return result.toString().trim(); + } + + private static String convertWholeNumberToWords(BigDecimal number) { + if (number.compareTo(BigDecimal.ZERO) == 0) { + return ZERO; + } + + StringBuilder words = new StringBuilder(); + int power = 0; + + while (number.compareTo(BigDecimal.ZERO) > 0) { + // Get the last three digits + BigDecimal[] divisionResult = number.divideAndRemainder(BigDecimal.valueOf(1000)); + int chunk = divisionResult[1].intValue(); + + if (chunk > 0) { + String chunkWords = convertChunk(chunk); + if (power > 0) { + words.insert(0, POWERS[power] + " "); + } + words.insert(0, chunkWords + " "); + } + + number = divisionResult[0]; // Continue with the remaining part + power++; + } + + return words.toString().trim(); + } + + private static String convertChunk(int number) { + String chunkWords; + + if (number < 20) { + chunkWords = UNITS[number]; + } else if (number < 100) { + chunkWords = TENS[number / 10] + (number % 10 > 0 ? " " + UNITS[number % 10] : ""); + } else { + chunkWords = UNITS[number / 100] + " Hundred" + (number % 100 > 0 ? " " + convertChunk(number % 100) : ""); + } + + return chunkWords; + } +} diff --git a/src/test/java/com/thealgorithms/conversions/NumberToWordsTest.java b/src/test/java/com/thealgorithms/conversions/NumberToWordsTest.java new file mode 100644 index 000000000000..7b264678daa4 --- /dev/null +++ b/src/test/java/com/thealgorithms/conversions/NumberToWordsTest.java @@ -0,0 +1,60 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.math.BigDecimal; +import org.junit.jupiter.api.Test; + +public class NumberToWordsTest { + + @Test + void testNullInput() { + assertEquals("Invalid Input", NumberToWords.convert(null), "Null input should return 'Invalid Input'"); + } + + @Test + void testZeroInput() { + assertEquals("Zero", NumberToWords.convert(BigDecimal.ZERO), "Zero input should return 'Zero'"); + } + + @Test + void testPositiveWholeNumbers() { + assertEquals("One", NumberToWords.convert(BigDecimal.ONE), "1 should convert to 'One'"); + assertEquals("One Thousand", NumberToWords.convert(new BigDecimal("1000")), "1000 should convert to 'One Thousand'"); + assertEquals("One Million", NumberToWords.convert(new BigDecimal("1000000")), "1000000 should convert to 'One Million'"); + } + + @Test + void testNegativeWholeNumbers() { + assertEquals("Negative One", NumberToWords.convert(new BigDecimal("-1")), "-1 should convert to 'Negative One'"); + assertEquals("Negative One Thousand", NumberToWords.convert(new BigDecimal("-1000")), "-1000 should convert to 'Negative One Thousand'"); + } + + @Test + void testFractionalNumbers() { + assertEquals("Zero Point One Two Three", NumberToWords.convert(new BigDecimal("0.123")), "0.123 should convert to 'Zero Point One Two Three'"); + assertEquals("Negative Zero Point Four Five Six", NumberToWords.convert(new BigDecimal("-0.456")), "-0.456 should convert to 'Negative Zero Point Four Five Six'"); + } + + @Test + void testLargeNumbers() { + assertEquals("Nine Hundred Ninety Nine Million Nine Hundred Ninety Nine Thousand Nine Hundred Ninety Nine", NumberToWords.convert(new BigDecimal("999999999")), "999999999 should convert correctly"); + assertEquals("One Trillion", NumberToWords.convert(new BigDecimal("1000000000000")), "1000000000000 should convert to 'One Trillion'"); + } + + @Test + void testNegativeLargeNumbers() { + assertEquals("Negative Nine Trillion Eight Hundred Seventy Six Billion Five Hundred Forty Three Million Two Hundred Ten Thousand Nine Hundred Eighty Seven", NumberToWords.convert(new BigDecimal("-9876543210987")), "-9876543210987 should convert correctly"); + } + + @Test + void testFloatingPointPrecision() { + assertEquals("One Million Point Zero Zero One", NumberToWords.convert(new BigDecimal("1000000.001")), "1000000.001 should convert to 'One Million Point Zero Zero One'"); + } + + @Test + void testEdgeCases() { + assertEquals("Zero", NumberToWords.convert(new BigDecimal("-0.0")), "-0.0 should convert to 'Zero'"); + assertEquals("Zero Point Zero Zero Zero Zero Zero Zero One", NumberToWords.convert(new BigDecimal("1E-7")), "1E-7 should convert to 'Zero Point Zero Zero Zero Zero Zero Zero One'"); + } +} From 5454e2ff626547eaac3edad1d1459f6bf5ca7e7f Mon Sep 17 00:00:00 2001 From: Sahil Kumar Valecha <106372522+sahilkumarvalecha@users.noreply.github.com> Date: Sat, 18 Jan 2025 22:34:34 +0500 Subject: [PATCH 025/146] Add DarkSort Algorithm (#6141) --- .../com/thealgorithms/sorts/DarkSort.java | 59 +++++++++++++++ .../com/thealgorithms/sorts/DarkSortTest.java | 74 +++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 src/main/java/com/thealgorithms/sorts/DarkSort.java create mode 100644 src/test/java/com/thealgorithms/sorts/DarkSortTest.java diff --git a/src/main/java/com/thealgorithms/sorts/DarkSort.java b/src/main/java/com/thealgorithms/sorts/DarkSort.java new file mode 100644 index 000000000000..4887d7d124ba --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/DarkSort.java @@ -0,0 +1,59 @@ +package com.thealgorithms.sorts; + +/** + * Dark Sort algorithm implementation. + * + * Dark Sort uses a temporary array to count occurrences of elements and + * reconstructs the sorted array based on the counts. + */ +class DarkSort { + + /** + * Sorts the array using the Dark Sort algorithm. + * + * @param unsorted the array to be sorted + * @return sorted array + */ + public Integer[] sort(Integer[] unsorted) { + if (unsorted == null || unsorted.length <= 1) { + return unsorted; + } + + int max = findMax(unsorted); // Find the maximum value in the array + + // Create a temporary array for counting occurrences + int[] temp = new int[max + 1]; + + // Count occurrences of each element + for (int value : unsorted) { + temp[value]++; + } + + // Reconstruct the sorted array + int index = 0; + for (int i = 0; i < temp.length; i++) { + while (temp[i] > 0) { + unsorted[index++] = i; + temp[i]--; + } + } + + return unsorted; + } + + /** + * Helper method to find the maximum value in an array. + * + * @param arr the array + * @return the maximum value + */ + private int findMax(Integer[] arr) { + int max = arr[0]; + for (int value : arr) { + if (value > max) { + max = value; + } + } + return max; + } +} diff --git a/src/test/java/com/thealgorithms/sorts/DarkSortTest.java b/src/test/java/com/thealgorithms/sorts/DarkSortTest.java new file mode 100644 index 000000000000..1df077e2ad74 --- /dev/null +++ b/src/test/java/com/thealgorithms/sorts/DarkSortTest.java @@ -0,0 +1,74 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import org.junit.jupiter.api.Test; + +class DarkSortTest { + + @Test + void testSortWithIntegers() { + Integer[] unsorted = {5, 3, 8, 6, 2, 7, 4, 1}; + Integer[] expected = {1, 2, 3, 4, 5, 6, 7, 8}; + + DarkSort darkSort = new DarkSort(); + Integer[] sorted = darkSort.sort(unsorted); + + assertArrayEquals(expected, sorted); + } + + @Test + void testEmptyArray() { + Integer[] unsorted = {}; + Integer[] expected = {}; + + DarkSort darkSort = new DarkSort(); + Integer[] sorted = darkSort.sort(unsorted); + + assertArrayEquals(expected, sorted); + } + + @Test + void testSingleElementArray() { + Integer[] unsorted = {42}; + Integer[] expected = {42}; + + DarkSort darkSort = new DarkSort(); + Integer[] sorted = darkSort.sort(unsorted); + + assertArrayEquals(expected, sorted); + } + + @Test + void testAlreadySortedArray() { + Integer[] unsorted = {1, 2, 3, 4, 5}; + Integer[] expected = {1, 2, 3, 4, 5}; + + DarkSort darkSort = new DarkSort(); + Integer[] sorted = darkSort.sort(unsorted); + + assertArrayEquals(expected, sorted); + } + + @Test + void testDuplicateElementsArray() { + Integer[] unsorted = {4, 2, 7, 2, 1, 4}; + Integer[] expected = {1, 2, 2, 4, 4, 7}; + + DarkSort darkSort = new DarkSort(); + Integer[] sorted = darkSort.sort(unsorted); + + assertArrayEquals(expected, sorted); + } + + @Test + void testNullArray() { + Integer[] unsorted = null; + + DarkSort darkSort = new DarkSort(); + Integer[] sorted = darkSort.sort(unsorted); + + assertNull(sorted, "Sorting a null array should return null"); + } +} From 30d0c064a7723f2c1e0dc485eefd31d747e1497a Mon Sep 17 00:00:00 2001 From: Muhammad Rizwan <88393515+rizwan-ilyas@users.noreply.github.com> Date: Sun, 19 Jan 2025 00:51:56 +0500 Subject: [PATCH 026/146] Fix absolute max bug (#6144) --- src/main/java/com/thealgorithms/maths/AbsoluteMax.java | 2 +- .../java/com/thealgorithms/maths/AbsoluteMaxTest.java | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/maths/AbsoluteMax.java b/src/main/java/com/thealgorithms/maths/AbsoluteMax.java index d0c3db3790a3..c32a408b6609 100644 --- a/src/main/java/com/thealgorithms/maths/AbsoluteMax.java +++ b/src/main/java/com/thealgorithms/maths/AbsoluteMax.java @@ -17,7 +17,7 @@ public static int getMaxValue(int... numbers) { } int absMax = numbers[0]; for (int i = 1; i < numbers.length; i++) { - if (Math.abs(numbers[i]) > Math.abs(absMax)) { + if (Math.abs(numbers[i]) > Math.abs(absMax) || (Math.abs(numbers[i]) == Math.abs(absMax) && numbers[i] > absMax)) { absMax = numbers[i]; } } diff --git a/src/test/java/com/thealgorithms/maths/AbsoluteMaxTest.java b/src/test/java/com/thealgorithms/maths/AbsoluteMaxTest.java index 70d2f64bc541..33461fbbc088 100644 --- a/src/test/java/com/thealgorithms/maths/AbsoluteMaxTest.java +++ b/src/test/java/com/thealgorithms/maths/AbsoluteMaxTest.java @@ -19,4 +19,12 @@ void testGetMaxValue() { void testGetMaxValueWithNoArguments() { assertThrows(IllegalArgumentException.class, AbsoluteMax::getMaxValue); } + + @Test + void testGetMaxValueWithSameAbsoluteValues() { + assertEquals(5, AbsoluteMax.getMaxValue(-5, 5)); + assertEquals(5, AbsoluteMax.getMaxValue(5, -5)); + assertEquals(12, AbsoluteMax.getMaxValue(-12, 9, 3, 12, 1)); + assertEquals(12, AbsoluteMax.getMaxValue(12, 9, 3, -12, 1)); + } } From 0e0539ea6c9d40189edb19bb462fdd7f72057170 Mon Sep 17 00:00:00 2001 From: Muhammad Rizwan <88393515+rizwan-ilyas@users.noreply.github.com> Date: Sun, 19 Jan 2025 21:50:43 +0500 Subject: [PATCH 027/146] Fix AbsoluteMin bug for equal absolute values (#6145) * fix-absolute-max-bug * clang-format for added junit * fix-absolute-min-bug --- src/main/java/com/thealgorithms/maths/AbsoluteMin.java | 2 +- .../java/com/thealgorithms/maths/AbsoluteMinTest.java | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/AbsoluteMin.java b/src/main/java/com/thealgorithms/maths/AbsoluteMin.java index 1ffe6d2e81bc..1b9575a330dd 100644 --- a/src/main/java/com/thealgorithms/maths/AbsoluteMin.java +++ b/src/main/java/com/thealgorithms/maths/AbsoluteMin.java @@ -19,7 +19,7 @@ public static int getMinValue(int... numbers) { var absMinWrapper = new Object() { int value = numbers[0]; }; - Arrays.stream(numbers).skip(1).filter(number -> Math.abs(number) < Math.abs(absMinWrapper.value)).forEach(number -> absMinWrapper.value = number); + Arrays.stream(numbers).skip(1).filter(number -> Math.abs(number) <= Math.abs(absMinWrapper.value)).forEach(number -> absMinWrapper.value = Math.min(absMinWrapper.value, number)); return absMinWrapper.value; } diff --git a/src/test/java/com/thealgorithms/maths/AbsoluteMinTest.java b/src/test/java/com/thealgorithms/maths/AbsoluteMinTest.java index 4b676ca634f7..dfca757fd877 100644 --- a/src/test/java/com/thealgorithms/maths/AbsoluteMinTest.java +++ b/src/test/java/com/thealgorithms/maths/AbsoluteMinTest.java @@ -15,7 +15,13 @@ void testGetMinValue() { @Test void testGetMinValueWithNoArguments() { - Exception exception = assertThrows(IllegalArgumentException.class, () -> AbsoluteMin.getMinValue()); + Exception exception = assertThrows(IllegalArgumentException.class, AbsoluteMin::getMinValue); assertEquals("Numbers array cannot be empty", exception.getMessage()); } + + @Test + void testGetMinValueWithSameAbsoluteValues() { + assertEquals(-5, AbsoluteMin.getMinValue(-5, 5)); + assertEquals(-5, AbsoluteMin.getMinValue(5, -5)); + } } From 364f66025a08494c172687ecb5081ef0605b50d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 21:58:53 +0000 Subject: [PATCH 028/146] Bump org.assertj:assertj-core from 3.27.2 to 3.27.3 (#6146) Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.27.2 to 3.27.3. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.2...assertj-build-3.27.3) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3fc2c89d339f..d246f378ba71 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 21 21 - 3.27.2 + 3.27.3 From f9efd382d1d5e0fa0ddb54c17283fc079b957386 Mon Sep 17 00:00:00 2001 From: Syed Rizvi Date: Sun, 26 Jan 2025 17:28:49 +0000 Subject: [PATCH 029/146] Fix: Replaced removeLast() with remove(current.size() - 1) (#6152) Fix: Replaced removeLast() with remove(current.size() - 1) for compatibility with ArrayList --- .../java/com/thealgorithms/backtracking/ArrayCombination.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java index 6569896bd1b7..f8cd0c40c20e 100644 --- a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java +++ b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java @@ -48,7 +48,7 @@ private static void combine(List> combinations, List curr for (int i = start; i < n; i++) { current.add(i); combine(combinations, current, i + 1, n, k); - current.removeLast(); // Backtrack + current.remove(current.size() - 1); // Backtrack } } } From 4ef06822caaea334ab4493d7e0b087d3c74c0acd Mon Sep 17 00:00:00 2001 From: varada610 Date: Mon, 27 Jan 2025 03:10:41 -0800 Subject: [PATCH 030/146] Create package prime, matrix and games (#6139) --- .../maths/GoldbachConjecture.java | 2 +- .../{ => Prime}/LiouvilleLambdaFunction.java | 4 +- .../MillerRabinPrimalityCheck.java | 2 +- .../maths/{ => Prime}/MobiusFunction.java | 4 +- .../maths/{ => Prime}/PrimeCheck.java | 2 +- .../maths/{ => Prime}/PrimeFactorization.java | 2 +- .../maths/{ => Prime}/SquareFreeInteger.java | 2 +- .../com/thealgorithms/maths/TwinPrime.java | 2 + .../{maths => matrix}/MatrixRank.java | 45 +-------------- .../thealgorithms/matrix/MirrorOfMatrix.java | 35 +++--------- .../matrixexponentiation/Fibonacci.java | 56 ++++--------------- .../{maths => matrix/utils}/MatrixUtil.java | 56 ++++++++++++++++++- .../{others => puzzlesandgames}/Sudoku.java | 2 +- .../TowerOfHanoi.java | 2 +- .../{misc => puzzlesandgames}/WordBoggle.java | 4 +- .../maths/SquareFreeIntegerTest.java | 1 + .../LiouvilleLambdaFunctionTest.java | 3 +- .../MillerRabinPrimalityCheckTest.java | 3 +- .../maths/{ => prime}/MobiusFunctionTest.java | 3 +- .../maths/{ => prime}/PrimeCheckTest.java | 3 +- .../{ => prime}/PrimeFactorizationTest.java | 3 +- .../{maths => matrix}/MatrixRankTest.java | 2 +- .../{maths => matrix}/MatrixUtilTest.java | 3 +- .../matrix/MirrorOfMatrixTest.java | 36 ++++++------ .../SudokuTest.java | 2 +- .../TowerOfHanoiTest.java | 2 +- .../WordBoggleTest.java | 2 +- 27 files changed, 123 insertions(+), 160 deletions(-) rename src/main/java/com/thealgorithms/maths/{ => Prime}/LiouvilleLambdaFunction.java (93%) rename src/main/java/com/thealgorithms/maths/{ => Prime}/MillerRabinPrimalityCheck.java (98%) rename src/main/java/com/thealgorithms/maths/{ => Prime}/MobiusFunction.java (96%) rename src/main/java/com/thealgorithms/maths/{ => Prime}/PrimeCheck.java (98%) rename src/main/java/com/thealgorithms/maths/{ => Prime}/PrimeFactorization.java (95%) rename src/main/java/com/thealgorithms/maths/{ => Prime}/SquareFreeInteger.java (97%) rename src/main/java/com/thealgorithms/{maths => matrix}/MatrixRank.java (77%) rename src/main/java/com/thealgorithms/{maths => matrix/utils}/MatrixUtil.java (62%) rename src/main/java/com/thealgorithms/{others => puzzlesandgames}/Sudoku.java (99%) rename src/main/java/com/thealgorithms/{others => puzzlesandgames}/TowerOfHanoi.java (98%) rename src/main/java/com/thealgorithms/{misc => puzzlesandgames}/WordBoggle.java (98%) rename src/test/java/com/thealgorithms/maths/{ => prime}/LiouvilleLambdaFunctionTest.java (94%) rename src/test/java/com/thealgorithms/maths/{ => prime}/MillerRabinPrimalityCheckTest.java (92%) rename src/test/java/com/thealgorithms/maths/{ => prime}/MobiusFunctionTest.java (96%) rename src/test/java/com/thealgorithms/maths/{ => prime}/PrimeCheckTest.java (89%) rename src/test/java/com/thealgorithms/maths/{ => prime}/PrimeFactorizationTest.java (93%) rename src/test/java/com/thealgorithms/{maths => matrix}/MatrixRankTest.java (98%) rename src/test/java/com/thealgorithms/{maths => matrix}/MatrixUtilTest.java (96%) rename src/test/java/com/thealgorithms/{others => puzzlesandgames}/SudokuTest.java (97%) rename src/test/java/com/thealgorithms/{others => puzzlesandgames}/TowerOfHanoiTest.java (97%) rename src/test/java/com/thealgorithms/{misc => puzzlesandgames}/WordBoggleTest.java (98%) diff --git a/src/main/java/com/thealgorithms/maths/GoldbachConjecture.java b/src/main/java/com/thealgorithms/maths/GoldbachConjecture.java index 52391bc100d8..4e962722ba88 100644 --- a/src/main/java/com/thealgorithms/maths/GoldbachConjecture.java +++ b/src/main/java/com/thealgorithms/maths/GoldbachConjecture.java @@ -1,6 +1,6 @@ package com.thealgorithms.maths; -import static com.thealgorithms.maths.PrimeCheck.isPrime; +import static com.thealgorithms.maths.Prime.PrimeCheck.isPrime; /** * This is a representation of the unsolved problem of Goldbach's Projection, according to which every diff --git a/src/main/java/com/thealgorithms/maths/LiouvilleLambdaFunction.java b/src/main/java/com/thealgorithms/maths/Prime/LiouvilleLambdaFunction.java similarity index 93% rename from src/main/java/com/thealgorithms/maths/LiouvilleLambdaFunction.java rename to src/main/java/com/thealgorithms/maths/Prime/LiouvilleLambdaFunction.java index c0f55f5e3485..73535b3aedae 100644 --- a/src/main/java/com/thealgorithms/maths/LiouvilleLambdaFunction.java +++ b/src/main/java/com/thealgorithms/maths/Prime/LiouvilleLambdaFunction.java @@ -1,4 +1,4 @@ -package com.thealgorithms.maths; +package com.thealgorithms.maths.Prime; /* * Java program for liouville lambda function @@ -24,7 +24,7 @@ private LiouvilleLambdaFunction() { * -1 when number has odd number of prime factors * @throws IllegalArgumentException when number is negative */ - static int liouvilleLambda(int number) { + public static int liouvilleLambda(int number) { if (number <= 0) { // throw exception when number is less than or is zero throw new IllegalArgumentException("Number must be greater than zero."); diff --git a/src/main/java/com/thealgorithms/maths/MillerRabinPrimalityCheck.java b/src/main/java/com/thealgorithms/maths/Prime/MillerRabinPrimalityCheck.java similarity index 98% rename from src/main/java/com/thealgorithms/maths/MillerRabinPrimalityCheck.java rename to src/main/java/com/thealgorithms/maths/Prime/MillerRabinPrimalityCheck.java index f889213abfcb..debe3a214a32 100644 --- a/src/main/java/com/thealgorithms/maths/MillerRabinPrimalityCheck.java +++ b/src/main/java/com/thealgorithms/maths/Prime/MillerRabinPrimalityCheck.java @@ -1,4 +1,4 @@ -package com.thealgorithms.maths; +package com.thealgorithms.maths.Prime; import java.util.Random; diff --git a/src/main/java/com/thealgorithms/maths/MobiusFunction.java b/src/main/java/com/thealgorithms/maths/Prime/MobiusFunction.java similarity index 96% rename from src/main/java/com/thealgorithms/maths/MobiusFunction.java rename to src/main/java/com/thealgorithms/maths/Prime/MobiusFunction.java index 915d0d9a6dae..3d4e4eff0f03 100644 --- a/src/main/java/com/thealgorithms/maths/MobiusFunction.java +++ b/src/main/java/com/thealgorithms/maths/Prime/MobiusFunction.java @@ -1,4 +1,4 @@ -package com.thealgorithms.maths; +package com.thealgorithms.maths.Prime; /* * Java program for mobius function @@ -25,7 +25,7 @@ private MobiusFunction() { * 0 when number has repeated prime factor * -1 when number has odd number of prime factors */ - static int mobius(int number) { + public static int mobius(int number) { if (number <= 0) { // throw exception when number is less than or is zero throw new IllegalArgumentException("Number must be greater than zero."); diff --git a/src/main/java/com/thealgorithms/maths/PrimeCheck.java b/src/main/java/com/thealgorithms/maths/Prime/PrimeCheck.java similarity index 98% rename from src/main/java/com/thealgorithms/maths/PrimeCheck.java rename to src/main/java/com/thealgorithms/maths/Prime/PrimeCheck.java index 628a819aeba4..91c490f70aef 100644 --- a/src/main/java/com/thealgorithms/maths/PrimeCheck.java +++ b/src/main/java/com/thealgorithms/maths/Prime/PrimeCheck.java @@ -1,4 +1,4 @@ -package com.thealgorithms.maths; +package com.thealgorithms.maths.Prime; import java.util.Scanner; diff --git a/src/main/java/com/thealgorithms/maths/PrimeFactorization.java b/src/main/java/com/thealgorithms/maths/Prime/PrimeFactorization.java similarity index 95% rename from src/main/java/com/thealgorithms/maths/PrimeFactorization.java rename to src/main/java/com/thealgorithms/maths/Prime/PrimeFactorization.java index 9ac50fd9043b..e12002b3d8c7 100644 --- a/src/main/java/com/thealgorithms/maths/PrimeFactorization.java +++ b/src/main/java/com/thealgorithms/maths/Prime/PrimeFactorization.java @@ -1,4 +1,4 @@ -package com.thealgorithms.maths; +package com.thealgorithms.maths.Prime; /* * Authors: diff --git a/src/main/java/com/thealgorithms/maths/SquareFreeInteger.java b/src/main/java/com/thealgorithms/maths/Prime/SquareFreeInteger.java similarity index 97% rename from src/main/java/com/thealgorithms/maths/SquareFreeInteger.java rename to src/main/java/com/thealgorithms/maths/Prime/SquareFreeInteger.java index 22e9fee00605..15c0a8a691cd 100644 --- a/src/main/java/com/thealgorithms/maths/SquareFreeInteger.java +++ b/src/main/java/com/thealgorithms/maths/Prime/SquareFreeInteger.java @@ -1,4 +1,4 @@ -package com.thealgorithms.maths; +package com.thealgorithms.maths.Prime; /* * Java program for Square free integer * This class has a function which checks diff --git a/src/main/java/com/thealgorithms/maths/TwinPrime.java b/src/main/java/com/thealgorithms/maths/TwinPrime.java index ef8de0d1018e..f4e546a2d7a4 100644 --- a/src/main/java/com/thealgorithms/maths/TwinPrime.java +++ b/src/main/java/com/thealgorithms/maths/TwinPrime.java @@ -9,6 +9,8 @@ * * */ +import com.thealgorithms.maths.Prime.PrimeCheck; + public final class TwinPrime { private TwinPrime() { } diff --git a/src/main/java/com/thealgorithms/maths/MatrixRank.java b/src/main/java/com/thealgorithms/matrix/MatrixRank.java similarity index 77% rename from src/main/java/com/thealgorithms/maths/MatrixRank.java rename to src/main/java/com/thealgorithms/matrix/MatrixRank.java index 7a628b92dccb..6692b6c37c60 100644 --- a/src/main/java/com/thealgorithms/maths/MatrixRank.java +++ b/src/main/java/com/thealgorithms/matrix/MatrixRank.java @@ -1,4 +1,6 @@ -package com.thealgorithms.maths; +package com.thealgorithms.matrix; + +import static com.thealgorithms.matrix.utils.MatrixUtil.validateInputMatrix; /** * This class provides a method to compute the rank of a matrix. @@ -63,47 +65,6 @@ private static double[][] deepCopy(double[][] matrix) { return matrixCopy; } - private static void validateInputMatrix(double[][] matrix) { - if (matrix == null) { - throw new IllegalArgumentException("The input matrix cannot be null"); - } - if (matrix.length == 0) { - throw new IllegalArgumentException("The input matrix cannot be empty"); - } - if (!hasValidRows(matrix)) { - throw new IllegalArgumentException("The input matrix cannot have null or empty rows"); - } - if (isJaggedMatrix(matrix)) { - throw new IllegalArgumentException("The input matrix cannot be jagged"); - } - } - - private static boolean hasValidRows(double[][] matrix) { - for (double[] row : matrix) { - if (row == null || row.length == 0) { - return false; - } - } - return true; - } - - /** - * @brief Checks if the input matrix is a jagged matrix. - * Jagged matrix is a matrix where the number of columns in each row is not the same. - * - * @param matrix The input matrix - * @return True if the input matrix is a jagged matrix, false otherwise - */ - private static boolean isJaggedMatrix(double[][] matrix) { - int numColumns = matrix[0].length; - for (double[] row : matrix) { - if (row.length != numColumns) { - return true; - } - } - return false; - } - /** * @brief The pivot row is the row in the matrix that is used to eliminate other rows and reduce the matrix to its row echelon form. * The pivot row is selected as the first row (from top to bottom) where the value in the current column (the pivot column) is not zero. diff --git a/src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java b/src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java index b24fcba75619..3a3055f38732 100644 --- a/src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java +++ b/src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java @@ -1,6 +1,9 @@ package com.thealgorithms.matrix; // Problem Statement + +import com.thealgorithms.matrix.utils.MatrixUtil; + /* We have given an array of m x n (where m is the number of rows and n is the number of columns). Print the new matrix in such a way that the new matrix is the mirror image of the original matrix. @@ -17,41 +20,17 @@ public final class MirrorOfMatrix { private MirrorOfMatrix() { } - public static int[][] mirrorMatrix(final int[][] originalMatrix) { - if (originalMatrix == null) { - // Handle invalid input - return null; - } - if (originalMatrix.length == 0) { - return new int[0][0]; - } - - checkInput(originalMatrix); + public static double[][] mirrorMatrix(final double[][] originalMatrix) { + MatrixUtil.validateInputMatrix(originalMatrix); int numRows = originalMatrix.length; int numCols = originalMatrix[0].length; - int[][] mirroredMatrix = new int[numRows][numCols]; + double[][] mirroredMatrix = new double[numRows][numCols]; for (int i = 0; i < numRows; i++) { - mirroredMatrix[i] = reverseRow(originalMatrix[i]); + mirroredMatrix[i] = MatrixUtil.reverseRow(originalMatrix[i]); } return mirroredMatrix; } - private static int[] reverseRow(final int[] inRow) { - int[] res = new int[inRow.length]; - for (int i = 0; i < inRow.length; ++i) { - res[i] = inRow[inRow.length - 1 - i]; - } - return res; - } - - private static void checkInput(final int[][] matrix) { - // Check if all rows have the same number of columns - for (int i = 1; i < matrix.length; i++) { - if (matrix[i].length != matrix[0].length) { - throw new IllegalArgumentException("The input is not a matrix."); - } - } - } } diff --git a/src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java b/src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java index 9c9f97b93ea4..85852713b9ba 100644 --- a/src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java +++ b/src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java @@ -1,6 +1,7 @@ package com.thealgorithms.matrix.matrixexponentiation; -import java.util.Scanner; +import com.thealgorithms.matrix.utils.MatrixUtil; +import java.math.BigDecimal; /** * @author Anirudh Buvanesh (https://github.com/anirudhb11) For more information @@ -12,39 +13,11 @@ private Fibonacci() { } // Exponentiation matrix for Fibonacci sequence - private static final int[][] FIB_MATRIX = {{1, 1}, {1, 0}}; - private static final int[][] IDENTITY_MATRIX = {{1, 0}, {0, 1}}; - // First 2 fibonacci numbers - private static final int[][] BASE_FIB_NUMBERS = {{1}, {0}}; + private static final BigDecimal ONE = BigDecimal.valueOf(1); + private static final BigDecimal ZERO = BigDecimal.valueOf(0); - /** - * Performs multiplication of 2 matrices - * - * @param matrix1 - * @param matrix2 - * @return The product of matrix1 and matrix2 - */ - private static int[][] matrixMultiplication(int[][] matrix1, int[][] matrix2) { - // Check if matrices passed can be multiplied - int rowsInMatrix1 = matrix1.length; - int columnsInMatrix1 = matrix1[0].length; - - int rowsInMatrix2 = matrix2.length; - int columnsInMatrix2 = matrix2[0].length; - - assert columnsInMatrix1 == rowsInMatrix2; - int[][] product = new int[rowsInMatrix1][columnsInMatrix2]; - for (int rowIndex = 0; rowIndex < rowsInMatrix1; rowIndex++) { - for (int colIndex = 0; colIndex < columnsInMatrix2; colIndex++) { - int matrixEntry = 0; - for (int intermediateIndex = 0; intermediateIndex < columnsInMatrix1; intermediateIndex++) { - matrixEntry += matrix1[rowIndex][intermediateIndex] * matrix2[intermediateIndex][colIndex]; - } - product[rowIndex][colIndex] = matrixEntry; - } - } - return product; - } + private static final BigDecimal[][] FIB_MATRIX = {{ONE, ONE}, {ONE, ZERO}}; + private static final BigDecimal[][] IDENTITY_MATRIX = {{ONE, ZERO}, {ZERO, ONE}}; /** * Calculates the fibonacci number using matrix exponentiaition technique @@ -53,26 +26,17 @@ private static int[][] matrixMultiplication(int[][] matrix1, int[][] matrix2) { * Outputs the nth * fibonacci number * @return a 2 X 1 array as { {F_n+1}, {F_n} } */ - public static int[][] fib(int n) { + public static BigDecimal[][] fib(int n) { if (n == 0) { return IDENTITY_MATRIX; } else { - int[][] cachedResult = fib(n / 2); - int[][] matrixExpResult = matrixMultiplication(cachedResult, cachedResult); + BigDecimal[][] cachedResult = fib(n / 2); + BigDecimal[][] matrixExpResult = MatrixUtil.multiply(cachedResult, cachedResult).get(); if (n % 2 == 0) { return matrixExpResult; } else { - return matrixMultiplication(FIB_MATRIX, matrixExpResult); + return MatrixUtil.multiply(FIB_MATRIX, matrixExpResult).get(); } } } - - public static void main(String[] args) { - // Returns [0, 1, 1, 2, 3, 5 ..] for n = [0, 1, 2, 3, 4, 5.. ] - Scanner sc = new Scanner(System.in); - int n = sc.nextInt(); - int[][] result = matrixMultiplication(fib(n), BASE_FIB_NUMBERS); - System.out.println("Fib(" + n + ") = " + result[1][0]); - sc.close(); - } } diff --git a/src/main/java/com/thealgorithms/maths/MatrixUtil.java b/src/main/java/com/thealgorithms/matrix/utils/MatrixUtil.java similarity index 62% rename from src/main/java/com/thealgorithms/maths/MatrixUtil.java rename to src/main/java/com/thealgorithms/matrix/utils/MatrixUtil.java index 7e462f92e185..5ff9e37f6b9a 100644 --- a/src/main/java/com/thealgorithms/maths/MatrixUtil.java +++ b/src/main/java/com/thealgorithms/matrix/utils/MatrixUtil.java @@ -1,4 +1,4 @@ -package com.thealgorithms.maths; +package com.thealgorithms.matrix.utils; import java.math.BigDecimal; import java.util.Optional; @@ -10,6 +10,7 @@ * @date: 31 October 2021 (Sunday) */ public final class MatrixUtil { + private MatrixUtil() { } @@ -18,11 +19,52 @@ private static boolean isValid(final BigDecimal[][] matrix) { } private static boolean hasEqualSizes(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2) { - return (isValid(matrix1) && isValid(matrix2) && matrix1.length == matrix2.length && matrix1[0].length == matrix2[0].length); + return isValid(matrix1) && isValid(matrix2) && matrix1.length == matrix2.length && matrix1[0].length == matrix2[0].length; } private static boolean canMultiply(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2) { - return (isValid(matrix1) && isValid(matrix2) && matrix1[0].length == matrix2.length); + return isValid(matrix1) && isValid(matrix2) && matrix1[0].length == matrix2.length; + } + + public static void validateInputMatrix(double[][] matrix) { + if (matrix == null) { + throw new IllegalArgumentException("The input matrix cannot be null"); + } + if (matrix.length == 0) { + throw new IllegalArgumentException("The input matrix cannot be empty"); + } + if (!hasValidRows(matrix)) { + throw new IllegalArgumentException("The input matrix cannot have null or empty rows"); + } + if (isJaggedMatrix(matrix)) { + throw new IllegalArgumentException("The input matrix cannot be jagged"); + } + } + + private static boolean hasValidRows(double[][] matrix) { + for (double[] row : matrix) { + if (row == null || row.length == 0) { + return false; + } + } + return true; + } + + /** + * @brief Checks if the input matrix is a jagged matrix. + * Jagged matrix is a matrix where the number of columns in each row is not the same. + * + * @param matrix The input matrix + * @return True if the input matrix is a jagged matrix, false otherwise + */ + private static boolean isJaggedMatrix(double[][] matrix) { + int numColumns = matrix[0].length; + for (double[] row : matrix) { + if (row.length != numColumns) { + return true; + } + } + return false; } private static Optional operate(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2, final BiFunction operation) { @@ -80,4 +122,12 @@ public static Optional multiply(final BigDecimal[][] matrix1, fi return Optional.of(result); } + + public static double[] reverseRow(final double[] inRow) { + double[] res = new double[inRow.length]; + for (int i = 0; i < inRow.length; ++i) { + res[i] = inRow[inRow.length - 1 - i]; + } + return res; + } } diff --git a/src/main/java/com/thealgorithms/others/Sudoku.java b/src/main/java/com/thealgorithms/puzzlesandgames/Sudoku.java similarity index 99% rename from src/main/java/com/thealgorithms/others/Sudoku.java rename to src/main/java/com/thealgorithms/puzzlesandgames/Sudoku.java index 0e88aee46f4d..fce665c4de00 100644 --- a/src/main/java/com/thealgorithms/others/Sudoku.java +++ b/src/main/java/com/thealgorithms/puzzlesandgames/Sudoku.java @@ -1,4 +1,4 @@ -package com.thealgorithms.others; +package com.thealgorithms.puzzlesandgames; /** * A class that provides methods to solve Sudoku puzzles of any n x n size diff --git a/src/main/java/com/thealgorithms/others/TowerOfHanoi.java b/src/main/java/com/thealgorithms/puzzlesandgames/TowerOfHanoi.java similarity index 98% rename from src/main/java/com/thealgorithms/others/TowerOfHanoi.java rename to src/main/java/com/thealgorithms/puzzlesandgames/TowerOfHanoi.java index 7017ed03f843..72e9a14ac070 100644 --- a/src/main/java/com/thealgorithms/others/TowerOfHanoi.java +++ b/src/main/java/com/thealgorithms/puzzlesandgames/TowerOfHanoi.java @@ -1,4 +1,4 @@ -package com.thealgorithms.others; +package com.thealgorithms.puzzlesandgames; import java.util.List; diff --git a/src/main/java/com/thealgorithms/misc/WordBoggle.java b/src/main/java/com/thealgorithms/puzzlesandgames/WordBoggle.java similarity index 98% rename from src/main/java/com/thealgorithms/misc/WordBoggle.java rename to src/main/java/com/thealgorithms/puzzlesandgames/WordBoggle.java index 8b629d68209b..ca1430f744ab 100644 --- a/src/main/java/com/thealgorithms/misc/WordBoggle.java +++ b/src/main/java/com/thealgorithms/puzzlesandgames/WordBoggle.java @@ -1,4 +1,4 @@ -package com.thealgorithms.misc; +package com.thealgorithms.puzzlesandgames; import java.util.ArrayList; import java.util.HashMap; @@ -8,9 +8,9 @@ import java.util.Set; public final class WordBoggle { + private WordBoggle() { } - /** * O(nm * 8^s + ws) time where n = width of boggle board, m = height of * boggle board, s = length of longest word in string array, w = length of diff --git a/src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java b/src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java index d7e16e02602b..5b35ee7bd9d0 100644 --- a/src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java +++ b/src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import com.thealgorithms.maths.Prime.SquareFreeInteger; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java b/src/test/java/com/thealgorithms/maths/prime/LiouvilleLambdaFunctionTest.java similarity index 94% rename from src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java rename to src/test/java/com/thealgorithms/maths/prime/LiouvilleLambdaFunctionTest.java index a2763047acf0..d32815c0b8a9 100644 --- a/src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java +++ b/src/test/java/com/thealgorithms/maths/prime/LiouvilleLambdaFunctionTest.java @@ -1,8 +1,9 @@ -package com.thealgorithms.maths; +package com.thealgorithms.maths.prime; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import com.thealgorithms.maths.Prime.LiouvilleLambdaFunction; import org.junit.jupiter.api.Test; class LiouvilleLambdaFunctionTest { diff --git a/src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java b/src/test/java/com/thealgorithms/maths/prime/MillerRabinPrimalityCheckTest.java similarity index 92% rename from src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java rename to src/test/java/com/thealgorithms/maths/prime/MillerRabinPrimalityCheckTest.java index d547cecf24cd..4defcd587758 100644 --- a/src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java +++ b/src/test/java/com/thealgorithms/maths/prime/MillerRabinPrimalityCheckTest.java @@ -1,8 +1,9 @@ -package com.thealgorithms.maths; +package com.thealgorithms.maths.prime; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import com.thealgorithms.maths.Prime.MillerRabinPrimalityCheck; import org.junit.jupiter.api.Test; class MillerRabinPrimalityCheckTest { diff --git a/src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java b/src/test/java/com/thealgorithms/maths/prime/MobiusFunctionTest.java similarity index 96% rename from src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java rename to src/test/java/com/thealgorithms/maths/prime/MobiusFunctionTest.java index f3a6514ce633..734d02477ba2 100644 --- a/src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java +++ b/src/test/java/com/thealgorithms/maths/prime/MobiusFunctionTest.java @@ -1,8 +1,9 @@ -package com.thealgorithms.maths; +package com.thealgorithms.maths.prime; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import com.thealgorithms.maths.Prime.MobiusFunction; import org.junit.jupiter.api.Test; class MobiusFunctionTest { diff --git a/src/test/java/com/thealgorithms/maths/PrimeCheckTest.java b/src/test/java/com/thealgorithms/maths/prime/PrimeCheckTest.java similarity index 89% rename from src/test/java/com/thealgorithms/maths/PrimeCheckTest.java rename to src/test/java/com/thealgorithms/maths/prime/PrimeCheckTest.java index c3e1634c51fe..2182bcd9cb16 100644 --- a/src/test/java/com/thealgorithms/maths/PrimeCheckTest.java +++ b/src/test/java/com/thealgorithms/maths/prime/PrimeCheckTest.java @@ -1,5 +1,6 @@ -package com.thealgorithms.maths; +package com.thealgorithms.maths.prime; +import com.thealgorithms.maths.Prime.PrimeCheck; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/PrimeFactorizationTest.java b/src/test/java/com/thealgorithms/maths/prime/PrimeFactorizationTest.java similarity index 93% rename from src/test/java/com/thealgorithms/maths/PrimeFactorizationTest.java rename to src/test/java/com/thealgorithms/maths/prime/PrimeFactorizationTest.java index 6994379d736a..79d685726261 100644 --- a/src/test/java/com/thealgorithms/maths/PrimeFactorizationTest.java +++ b/src/test/java/com/thealgorithms/maths/prime/PrimeFactorizationTest.java @@ -1,7 +1,8 @@ -package com.thealgorithms.maths; +package com.thealgorithms.maths.prime; import static org.junit.jupiter.api.Assertions.assertEquals; +import com.thealgorithms.maths.Prime.PrimeFactorization; import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/com/thealgorithms/maths/MatrixRankTest.java b/src/test/java/com/thealgorithms/matrix/MatrixRankTest.java similarity index 98% rename from src/test/java/com/thealgorithms/maths/MatrixRankTest.java rename to src/test/java/com/thealgorithms/matrix/MatrixRankTest.java index 415b84ec43f8..33a0196b7bf7 100644 --- a/src/test/java/com/thealgorithms/maths/MatrixRankTest.java +++ b/src/test/java/com/thealgorithms/matrix/MatrixRankTest.java @@ -1,4 +1,4 @@ -package com.thealgorithms.maths; +package com.thealgorithms.matrix; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/src/test/java/com/thealgorithms/maths/MatrixUtilTest.java b/src/test/java/com/thealgorithms/matrix/MatrixUtilTest.java similarity index 96% rename from src/test/java/com/thealgorithms/maths/MatrixUtilTest.java rename to src/test/java/com/thealgorithms/matrix/MatrixUtilTest.java index b954e6ff7511..78947b1e70cb 100644 --- a/src/test/java/com/thealgorithms/maths/MatrixUtilTest.java +++ b/src/test/java/com/thealgorithms/matrix/MatrixUtilTest.java @@ -1,7 +1,8 @@ -package com.thealgorithms.maths; +package com.thealgorithms.matrix; import static org.junit.jupiter.api.Assertions.assertTrue; +import com.thealgorithms.matrix.utils.MatrixUtil; import java.math.BigDecimal; import java.util.Objects; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java b/src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java index 2d68e1faaa17..2e4370922370 100644 --- a/src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java +++ b/src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java @@ -1,7 +1,7 @@ package com.thealgorithms.matrix; import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; @@ -10,44 +10,44 @@ class MirrorOfMatrixTest { @Test void testMirrorMatrixRegularMatrix() { - int[][] originalMatrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; - int[][] expectedMirrorMatrix = {{3, 2, 1}, {6, 5, 4}, {9, 8, 7}}; - int[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix); + double[][] originalMatrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; + double[][] expectedMirrorMatrix = {{3, 2, 1}, {6, 5, 4}, {9, 8, 7}}; + double[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix); assertArrayEquals(expectedMirrorMatrix, mirroredMatrix); } @Test void testMirrorMatrixEmptyMatrix() { - int[][] originalMatrix = {}; - int[][] expectedMirrorMatrix = {}; - int[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix); - assertArrayEquals(expectedMirrorMatrix, mirroredMatrix); + double[][] originalMatrix = {}; + Exception e = assertThrows(IllegalArgumentException.class, () -> MirrorOfMatrix.mirrorMatrix(originalMatrix)); + assertEquals("The input matrix cannot be empty", e.getMessage()); } @Test void testMirrorMatrixSingleElementMatrix() { - int[][] originalMatrix = {{42}}; - int[][] expectedMirrorMatrix = {{42}}; - int[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix); + double[][] originalMatrix = {{42}}; + double[][] expectedMirrorMatrix = {{42}}; + double[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix); assertArrayEquals(expectedMirrorMatrix, mirroredMatrix); } @Test void testMirrorMatrixMultipleRowsOneColumnMatrix() { - int[][] originalMatrix = {{1}, {2}, {3}, {4}}; - int[][] expectedMirrorMatrix = {{1}, {2}, {3}, {4}}; - int[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix); + double[][] originalMatrix = {{1}, {2}, {3}, {4}}; + double[][] expectedMirrorMatrix = {{1}, {2}, {3}, {4}}; + double[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix); assertArrayEquals(expectedMirrorMatrix, mirroredMatrix); } @Test void testMirrorMatrixNullInput() { - int[][] originalMatrix = null; - assertNull(MirrorOfMatrix.mirrorMatrix(originalMatrix)); + double[][] originalMatrix = null; + Exception e = assertThrows(IllegalArgumentException.class, () -> MirrorOfMatrix.mirrorMatrix(originalMatrix)); + assertEquals("The input matrix cannot be null", e.getMessage()); } @Test - void testMirrotMarixThrows() { - assertThrows(IllegalArgumentException.class, () -> MirrorOfMatrix.mirrorMatrix(new int[][] {{1}, {2, 3}})); + void testMirrorMatrixThrows() { + assertThrows(IllegalArgumentException.class, () -> MirrorOfMatrix.mirrorMatrix(new double[][] {{1}, {2, 3}})); } } diff --git a/src/test/java/com/thealgorithms/others/SudokuTest.java b/src/test/java/com/thealgorithms/puzzlesandgames/SudokuTest.java similarity index 97% rename from src/test/java/com/thealgorithms/others/SudokuTest.java rename to src/test/java/com/thealgorithms/puzzlesandgames/SudokuTest.java index 5018b2768302..7fb96dcf805f 100644 --- a/src/test/java/com/thealgorithms/others/SudokuTest.java +++ b/src/test/java/com/thealgorithms/puzzlesandgames/SudokuTest.java @@ -1,4 +1,4 @@ -package com.thealgorithms.others; +package com.thealgorithms.puzzlesandgames; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/com/thealgorithms/others/TowerOfHanoiTest.java b/src/test/java/com/thealgorithms/puzzlesandgames/TowerOfHanoiTest.java similarity index 97% rename from src/test/java/com/thealgorithms/others/TowerOfHanoiTest.java rename to src/test/java/com/thealgorithms/puzzlesandgames/TowerOfHanoiTest.java index ca9376dd48eb..42669eb03bb4 100644 --- a/src/test/java/com/thealgorithms/others/TowerOfHanoiTest.java +++ b/src/test/java/com/thealgorithms/puzzlesandgames/TowerOfHanoiTest.java @@ -1,4 +1,4 @@ -package com.thealgorithms.others; +package com.thealgorithms.puzzlesandgames; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/src/test/java/com/thealgorithms/misc/WordBoggleTest.java b/src/test/java/com/thealgorithms/puzzlesandgames/WordBoggleTest.java similarity index 98% rename from src/test/java/com/thealgorithms/misc/WordBoggleTest.java rename to src/test/java/com/thealgorithms/puzzlesandgames/WordBoggleTest.java index 1d4ed7c5e737..ef5d3c92eb5e 100644 --- a/src/test/java/com/thealgorithms/misc/WordBoggleTest.java +++ b/src/test/java/com/thealgorithms/puzzlesandgames/WordBoggleTest.java @@ -1,4 +1,4 @@ -package com.thealgorithms.misc; +package com.thealgorithms.puzzlesandgames; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; From 4d667e1b76001617f83b4ad1e662a0af14117c28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 22:23:25 +0100 Subject: [PATCH 031/146] Bump com.puppycrawl.tools:checkstyle from 10.21.1 to 10.21.2 (#6154) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.21.1 to 10.21.2. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.21.1...checkstyle-10.21.2) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d246f378ba71..7900c6f2d956 100644 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,7 @@ com.puppycrawl.tools checkstyle - 10.21.1 + 10.21.2 From d4b28b348e0ccd7423d0981499f85958382d1522 Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Tue, 28 Jan 2025 11:33:58 +0100 Subject: [PATCH 032/146] Add Constrained Shortest Path Problem (CSPP) / Shortest Path Problem with Resource Constraints (SPPRC) (#6155) --- .../graph/ConstrainedShortestPath.java | 123 ++++++++++ .../graph/ConstrainedShortestPathTest.java | 218 ++++++++++++++++++ 2 files changed, 341 insertions(+) create mode 100644 src/main/java/com/thealgorithms/graph/ConstrainedShortestPath.java create mode 100644 src/test/java/com/thealgorithms/graph/ConstrainedShortestPathTest.java diff --git a/src/main/java/com/thealgorithms/graph/ConstrainedShortestPath.java b/src/main/java/com/thealgorithms/graph/ConstrainedShortestPath.java new file mode 100644 index 000000000000..f397989911d9 --- /dev/null +++ b/src/main/java/com/thealgorithms/graph/ConstrainedShortestPath.java @@ -0,0 +1,123 @@ +package com.thealgorithms.graph; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * This class implements a solution for the Constrained Shortest Path Problem (CSPP). + * also known as Shortest Path Problem with Resource Constraints (SPPRC). + * The goal is to find the shortest path between two nodes while ensuring that + * the resource constraint is not exceeded. + * + * @author Deniz Altunkapan + */ +public class ConstrainedShortestPath { + + /** + * Represents a graph using an adjacency list. + * This graph is designed for the Constrained Shortest Path Problem (CSPP). + */ + public static class Graph { + + private List> adjacencyList; + + public Graph(int numNodes) { + adjacencyList = new ArrayList<>(); + for (int i = 0; i < numNodes; i++) { + adjacencyList.add(new ArrayList<>()); + } + } + + /** + * Adds an edge to the graph. + * @param from the starting node + * @param to the ending node + * @param cost the cost of the edge + * @param resource the resource required to traverse the edge + */ + public void addEdge(int from, int to, int cost, int resource) { + adjacencyList.get(from).add(new Edge(from, to, cost, resource)); + } + + /** + * Gets the edges that are adjacent to a given node. + * @param node the node to get the edges for + * @return the list of edges adjacent to the node + */ + public List getEdges(int node) { + return adjacencyList.get(node); + } + + /** + * Gets the number of nodes in the graph. + * @return the number of nodes + */ + public int getNumNodes() { + return adjacencyList.size(); + } + + public record Edge(int from, int to, int cost, int resource) { + } + } + + private Graph graph; + private int maxResource; + + /** + * Constructs a CSPSolver with the given graph and maximum resource constraint. + * + * @param graph the graph representing the problem + * @param maxResource the maximum allowable resource + */ + public ConstrainedShortestPath(Graph graph, int maxResource) { + this.graph = graph; + this.maxResource = maxResource; + } + + /** + * Solves the CSP to find the shortest path from the start node to the target node + * without exceeding the resource constraint. + * + * @param start the starting node + * @param target the target node + * @return the minimum cost to reach the target node within the resource constraint, + * or -1 if no valid path exists + */ + public int solve(int start, int target) { + int numNodes = graph.getNumNodes(); + int[][] dp = new int[maxResource + 1][numNodes]; + + // Initialize dp table with maximum values + for (int i = 0; i <= maxResource; i++) { + Arrays.fill(dp[i], Integer.MAX_VALUE); + } + dp[0][start] = 0; + + // Dynamic Programming: Iterate over resources and nodes + for (int r = 0; r <= maxResource; r++) { + for (int u = 0; u < numNodes; u++) { + if (dp[r][u] == Integer.MAX_VALUE) { + continue; + } + for (Graph.Edge edge : graph.getEdges(u)) { + int v = edge.to(); + int cost = edge.cost(); + int resource = edge.resource(); + + if (r + resource <= maxResource) { + dp[r + resource][v] = Math.min(dp[r + resource][v], dp[r][u] + cost); + } + } + } + } + + // Find the minimum cost to reach the target node + int minCost = Integer.MAX_VALUE; + for (int r = 0; r <= maxResource; r++) { + minCost = Math.min(minCost, dp[r][target]); + } + + return minCost == Integer.MAX_VALUE ? -1 : minCost; + } +} diff --git a/src/test/java/com/thealgorithms/graph/ConstrainedShortestPathTest.java b/src/test/java/com/thealgorithms/graph/ConstrainedShortestPathTest.java new file mode 100644 index 000000000000..eccd359f2634 --- /dev/null +++ b/src/test/java/com/thealgorithms/graph/ConstrainedShortestPathTest.java @@ -0,0 +1,218 @@ +package com.thealgorithms.graph; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.thealgorithms.graph.ConstrainedShortestPath.Graph; +import org.junit.jupiter.api.Test; + +public class ConstrainedShortestPathTest { + + /** + * Tests a simple linear graph to verify if the solver calculates the shortest path correctly. + * Expected: The minimal path cost from node 0 to node 2 should be 5 while not exceeding the resource limit. + */ + @Test + public void testSimpleGraph() { + Graph graph = new Graph(3); + graph.addEdge(0, 1, 2, 3); + graph.addEdge(1, 2, 3, 2); + + int maxResource = 5; + ConstrainedShortestPath solver = new ConstrainedShortestPath(graph, maxResource); + + assertEquals(5, solver.solve(0, 2)); + } + + /** + * Tests a graph where no valid path exists due to resource constraints. + * Expected: The solver should return -1, indicating no path is feasible. + */ + @Test + public void testNoPath() { + Graph graph = new Graph(3); + graph.addEdge(0, 1, 2, 6); + graph.addEdge(1, 2, 3, 6); + + int maxResource = 5; + ConstrainedShortestPath solver = new ConstrainedShortestPath(graph, maxResource); + + assertEquals(-1, solver.solve(0, 2)); + } + + /** + * Tests a graph with multiple paths between source and destination. + * Expected: The solver should choose the path with the minimal cost of 5, considering the resource limit. + */ + @Test + public void testMultiplePaths() { + Graph graph = new Graph(4); + graph.addEdge(0, 1, 1, 1); + graph.addEdge(1, 3, 5, 2); + graph.addEdge(0, 2, 2, 1); + graph.addEdge(2, 3, 3, 2); + + int maxResource = 3; + ConstrainedShortestPath solver = new ConstrainedShortestPath(graph, maxResource); + + assertEquals(5, solver.solve(0, 3)); + } + + /** + * Verifies that the solver allows a path exactly matching the resource limit. + * Expected: The path is valid with a total cost of 5. + */ + @Test + public void testExactResourceLimit() { + Graph graph = new Graph(3); + graph.addEdge(0, 1, 2, 3); + graph.addEdge(1, 2, 3, 2); + + int maxResource = 5; + ConstrainedShortestPath solver = new ConstrainedShortestPath(graph, maxResource); + + assertEquals(5, solver.solve(0, 2)); + } + + /** + * Tests a disconnected graph where the destination node cannot be reached. + * Expected: The solver should return -1, as the destination is unreachable. + */ + @Test + public void testDisconnectedGraph() { + Graph graph = new Graph(4); + graph.addEdge(0, 1, 2, 2); + graph.addEdge(2, 3, 3, 2); + + int maxResource = 5; + ConstrainedShortestPath solver = new ConstrainedShortestPath(graph, maxResource); + + assertEquals(-1, solver.solve(0, 3)); + } + + /** + * Tests a graph with cycles to ensure the solver does not fall into infinite loops and correctly calculates costs. + * Expected: The solver should compute the minimal path cost of 6. + */ + @Test + public void testGraphWithCycles() { + Graph graph = new Graph(4); + graph.addEdge(0, 1, 2, 1); + graph.addEdge(1, 2, 3, 1); + graph.addEdge(2, 0, 1, 1); + graph.addEdge(1, 3, 4, 2); + + int maxResource = 3; + ConstrainedShortestPath solver = new ConstrainedShortestPath(graph, maxResource); + + assertEquals(6, solver.solve(0, 3)); + } + + /** + * Tests the solver's performance and correctness on a large linear graph with 1000 nodes. + * Expected: The solver should efficiently calculate the shortest path with a cost of 999. + */ + @Test + public void testLargeGraphPerformance() { + int nodeCount = 1000; + Graph graph = new Graph(nodeCount); + for (int i = 0; i < nodeCount - 1; i++) { + graph.addEdge(i, i + 1, 1, 1); + } + + int maxResource = 1000; + ConstrainedShortestPath solver = new ConstrainedShortestPath(graph, maxResource); + + assertEquals(999, solver.solve(0, nodeCount - 1)); + } + + /** + * Tests a graph with isolated nodes to ensure the solver recognizes unreachable destinations. + * Expected: The solver should return -1 for unreachable nodes. + */ + @Test + public void testIsolatedNodes() { + Graph graph = new Graph(5); + graph.addEdge(0, 1, 2, 1); + graph.addEdge(1, 2, 3, 1); + + int maxResource = 5; + ConstrainedShortestPath solver = new ConstrainedShortestPath(graph, maxResource); + + assertEquals(-1, solver.solve(0, 3)); + } + + /** + * Tests a cyclic large graph with multiple overlapping paths. + * Expected: The solver should calculate the shortest path cost of 5. + */ + @Test + public void testCyclicLargeGraph() { + Graph graph = new Graph(10); + for (int i = 0; i < 9; i++) { + graph.addEdge(i, (i + 1) % 10, 1, 1); + } + graph.addEdge(0, 5, 5, 3); + + int maxResource = 10; + ConstrainedShortestPath solver = new ConstrainedShortestPath(graph, maxResource); + + assertEquals(5, solver.solve(0, 5)); + } + + /** + * Tests a large complex graph with multiple paths and varying resource constraints. + * Expected: The solver should identify the optimal path with a cost of 19 within the resource limit. + */ + @Test + public void testLargeComplexGraph() { + Graph graph = new Graph(10); + graph.addEdge(0, 1, 4, 2); + graph.addEdge(0, 2, 3, 3); + graph.addEdge(1, 3, 2, 1); + graph.addEdge(2, 3, 5, 2); + graph.addEdge(2, 4, 8, 4); + graph.addEdge(3, 5, 7, 3); + graph.addEdge(3, 6, 6, 2); + graph.addEdge(4, 6, 3, 2); + graph.addEdge(5, 7, 1, 1); + graph.addEdge(6, 7, 2, 2); + graph.addEdge(7, 8, 3, 1); + graph.addEdge(8, 9, 2, 1); + + int maxResource = 10; + ConstrainedShortestPath solver = new ConstrainedShortestPath(graph, maxResource); + + assertEquals(19, solver.solve(0, 9)); + } + + /** + * Edge case test where the graph has only one node and no edges. + * Expected: The minimal path cost is 0, as the start and destination are the same. + */ + @Test + public void testSingleNodeGraph() { + Graph graph = new Graph(1); + + int maxResource = 0; + ConstrainedShortestPath solver = new ConstrainedShortestPath(graph, maxResource); + + assertEquals(0, solver.solve(0, 0)); + } + + /** + * Tests a graph with multiple paths but a tight resource constraint. + * Expected: The solver should return -1 if no path can be found within the resource limit. + */ + @Test + public void testTightResourceConstraint() { + Graph graph = new Graph(4); + graph.addEdge(0, 1, 3, 4); + graph.addEdge(1, 2, 1, 2); + graph.addEdge(0, 2, 2, 2); + + int maxResource = 3; + ConstrainedShortestPath solver = new ConstrainedShortestPath(graph, maxResource); + + assertEquals(2, solver.solve(0, 2)); + } +} From 3313ddc7233a3b7751cdf3ccdd0954bf27c1f865 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 21:34:14 +0000 Subject: [PATCH 033/146] Bump gitpod/workspace-java-21 from 2024-11-26-08-43-19 to 2025-02-10-10-54-28 (#6162) Bump gitpod/workspace-java-21 Bumps gitpod/workspace-java-21 from 2024-11-26-08-43-19 to 2025-02-10-10-54-28. --- updated-dependencies: - dependency-name: gitpod/workspace-java-21 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .gitpod.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile index 4b1885ffa388..ea6d32a5a377 100644 --- a/.gitpod.dockerfile +++ b/.gitpod.dockerfile @@ -1,4 +1,4 @@ -FROM gitpod/workspace-java-21:2024-11-26-08-43-19 +FROM gitpod/workspace-java-21:2025-02-10-10-54-28 ENV LLVM_SCRIPT="tmp_llvm.sh" From 63ce6b8ca57e99203dbc5129a50662d5cc48799e Mon Sep 17 00:00:00 2001 From: Niklas Hoefflin <122729995+itakurah@users.noreply.github.com> Date: Thu, 13 Feb 2025 21:33:52 +0100 Subject: [PATCH 034/146] Refactor LWWElementSet (#6164) --- DIRECTORY.md | 51 +++--- .../datastructures/crdt/LWWElementSet.java | 170 ++++++++---------- .../crdt/LWWElementSetTest.java | 120 ++++++------- 3 files changed, 164 insertions(+), 177 deletions(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index 4fa1392a3c17..6ccaf0b38e7f 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -332,6 +332,7 @@ * [MidpointEllipse](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/geometry/MidpointEllipse.java) * [Point](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/geometry/Point.java) * graph + * [ConstrainedShortestPath](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/graph/ConstrainedShortestPath.java) * [StronglyConnectedComponentOptimized](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/graph/StronglyConnectedComponentOptimized.java) * greedyalgorithms * [ActivitySelection](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java) @@ -419,18 +420,13 @@ * [LeastCommonMultiple](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LeastCommonMultiple.java) * [LeonardoNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LeonardoNumber.java) * [LinearDiophantineEquationsSolver](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java) - * [LiouvilleLambdaFunction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LiouvilleLambdaFunction.java) * [LongDivision](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LongDivision.java) * [LucasSeries](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LucasSeries.java) * [MagicSquare](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MagicSquare.java) - * [MatrixRank](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MatrixRank.java) - * [MatrixUtil](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MatrixUtil.java) * [MaxValue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MaxValue.java) * [Means](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Means.java) * [Median](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Median.java) - * [MillerRabinPrimalityCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MillerRabinPrimalityCheck.java) * [MinValue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MinValue.java) - * [MobiusFunction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MobiusFunction.java) * [Mode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Mode.java) * [NonRepeatingElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/NonRepeatingElement.java) * [NthUglyNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/NthUglyNumber.java) @@ -447,8 +443,13 @@ * [Pow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Pow.java) * [PowerOfTwoOrNot](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java) * [PowerUsingRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java) - * [PrimeCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PrimeCheck.java) - * [PrimeFactorization](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PrimeFactorization.java) + * Prime + * [LiouvilleLambdaFunction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Prime/LiouvilleLambdaFunction.java) + * [MillerRabinPrimalityCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Prime/MillerRabinPrimalityCheck.java) + * [MobiusFunction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Prime/MobiusFunction.java) + * [PrimeCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Prime/PrimeCheck.java) + * [PrimeFactorization](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Prime/PrimeFactorization.java) + * [SquareFreeInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Prime/SquareFreeInteger.java) * [PronicNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PronicNumber.java) * [PythagoreanTriple](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java) * [QuadraticEquationSolver](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/QuadraticEquationSolver.java) @@ -458,7 +459,6 @@ * [SieveOfEratosthenes](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java) * [SimpsonIntegration](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java) * [SolovayStrassenPrimalityTest](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SolovayStrassenPrimalityTest.java) - * [SquareFreeInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SquareFreeInteger.java) * [SquareRootWithBabylonianMethod](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java) * [SquareRootWithNewtonRaphsonMethod](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java) * [StandardDeviation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/StandardDeviation.java) @@ -478,11 +478,14 @@ * [InverseOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/InverseOfMatrix.java) * matrixexponentiation * [Fibonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java) + * [MatrixRank](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/MatrixRank.java) * [MatrixTranspose](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/MatrixTranspose.java) * [MedianOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/MedianOfMatrix.java) * [MirrorOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java) * [PrintAMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java) * [RotateMatrixBy90Degrees](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/RotateMatrixBy90Degrees.java) + * utils + * [MatrixUtil](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/utils/MatrixUtil.java) * misc * [ColorContrastRatio](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java) * [MapReduce](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MapReduce.java) @@ -499,7 +502,6 @@ * [Sparsity](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/Sparsity.java) * [ThreeSumProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/ThreeSumProblem.java) * [TwoSumProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/TwoSumProblem.java) - * [WordBoggle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/WordBoggle.java) * others * [ArrayLeftRotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ArrayLeftRotation.java) * [ArrayRightRotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ArrayRightRotation.java) @@ -539,10 +541,12 @@ * [RemoveDuplicateFromString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/RemoveDuplicateFromString.java) * [ReverseStackUsingRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java) * [SkylineProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/SkylineProblem.java) - * [Sudoku](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Sudoku.java) - * [TowerOfHanoi](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/TowerOfHanoi.java) * [TwoPointers](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/TwoPointers.java) * [Verhoeff](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Verhoeff.java) + * puzzlesandgames + * [Sudoku](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/puzzlesandgames/Sudoku.java) + * [TowerOfHanoi](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/puzzlesandgames/TowerOfHanoi.java) + * [WordBoggle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/puzzlesandgames/WordBoggle.java) * recursion * [FibonacciSeries](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/recursion/FibonacciSeries.java) * [GenerateSubsets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/recursion/GenerateSubsets.java) @@ -623,6 +627,7 @@ * [CombSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CombSort.java) * [CountingSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CountingSort.java) * [CycleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CycleSort.java) + * [DarkSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DarkSort.java) * [DualPivotQuickSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java) * [DutchNationalFlagSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java) * [ExchangeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/ExchangeSort.java) @@ -1008,6 +1013,7 @@ * [MidpointCircleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/geometry/MidpointCircleTest.java) * [MidpointEllipseTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/geometry/MidpointEllipseTest.java) * graph + * [ConstrainedShortestPathTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/graph/ConstrainedShortestPathTest.java) * [StronglyConnectedComponentOptimizedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/graph/StronglyConnectedComponentOptimizedTest.java) * greedyalgorithms * [ActivitySelectionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java) @@ -1087,17 +1093,12 @@ * [KrishnamurthyNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/KrishnamurthyNumberTest.java) * [LeastCommonMultipleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LeastCommonMultipleTest.java) * [LeonardoNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LeonardoNumberTest.java) - * [LiouvilleLambdaFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java) * [LongDivisionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LongDivisionTest.java) * [LucasSeriesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LucasSeriesTest.java) - * [MatrixRankTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MatrixRankTest.java) - * [MatrixUtilTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MatrixUtilTest.java) * [MaxValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MaxValueTest.java) * [MeansTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MeansTest.java) * [MedianTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MedianTest.java) - * [MillerRabinPrimalityCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java) * [MinValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MinValueTest.java) - * [MobiusFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java) * [ModeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ModeTest.java) * [NonRepeatingElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/NonRepeatingElementTest.java) * [NthUglyNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/NthUglyNumberTest.java) @@ -1113,8 +1114,12 @@ * [PowerOfTwoOrNotTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java) * [PowerUsingRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java) * [PowTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PowTest.java) - * [PrimeCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PrimeCheckTest.java) - * [PrimeFactorizationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PrimeFactorizationTest.java) + * prime + * [LiouvilleLambdaFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/prime/LiouvilleLambdaFunctionTest.java) + * [MillerRabinPrimalityCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/prime/MillerRabinPrimalityCheckTest.java) + * [MobiusFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/prime/MobiusFunctionTest.java) + * [PrimeCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/prime/PrimeCheckTest.java) + * [PrimeFactorizationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/prime/PrimeFactorizationTest.java) * [PronicNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PronicNumberTest.java) * [PythagoreanTripleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java) * [QuadraticEquationSolverTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/QuadraticEquationSolverTest.java) @@ -1139,7 +1144,9 @@ * [VolumeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/VolumeTest.java) * matrix * [InverseOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/InverseOfMatrixTest.java) + * [MatrixRankTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MatrixRankTest.java) * [MatrixTransposeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MatrixTransposeTest.java) + * [MatrixUtilTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MatrixUtilTest.java) * [MedianOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MedianOfMatrixTest.java) * [MirrorOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java) * [TestPrintMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/TestPrintMatrixInSpiralOrder.java) @@ -1154,7 +1161,6 @@ * [SparsityTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/SparsityTest.java) * [ThreeSumProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/ThreeSumProblemTest.java) * [TwoSumProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/TwoSumProblemTest.java) - * [WordBoggleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/WordBoggleTest.java) * others * [ArrayLeftRotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java) * [ArrayRightRotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ArrayRightRotationTest.java) @@ -1182,10 +1188,12 @@ * [RemoveDuplicateFromStringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/RemoveDuplicateFromStringTest.java) * [ReverseStackUsingRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ReverseStackUsingRecursionTest.java) * [SkylineProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/SkylineProblemTest.java) - * [SudokuTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/SudokuTest.java) - * [TowerOfHanoiTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TowerOfHanoiTest.java) * [TwoPointersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TwoPointersTest.java) * [WorstFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java) + * puzzlesandgames + * [SudokuTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/puzzlesandgames/SudokuTest.java) + * [TowerOfHanoiTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/puzzlesandgames/TowerOfHanoiTest.java) + * [WordBoggleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/puzzlesandgames/WordBoggleTest.java) * recursion * [FibonacciSeriesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/recursion/FibonacciSeriesTest.java) * [GenerateSubsetsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/recursion/GenerateSubsetsTest.java) @@ -1267,6 +1275,7 @@ * [CombSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CombSortTest.java) * [CountingSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CountingSortTest.java) * [CycleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CycleSortTest.java) + * [DarkSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DarkSortTest.java) * [DualPivotQuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java) * [DutchNationalFlagSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java) * [ExchangeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java) diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java b/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java index 2c6ce8a427d1..d33bd3ee84d9 100644 --- a/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java +++ b/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java @@ -1,53 +1,33 @@ package com.thealgorithms.datastructures.crdt; +import java.time.Instant; import java.util.HashMap; import java.util.Map; /** - * Last-Write-Wins Element Set (LWWElementSet) is a state-based CRDT (Conflict-free Replicated Data Type) - * designed for managing sets in a distributed and concurrent environment. It supports the addition and removal - * of elements, using timestamps to determine the order of operations. The set is split into two subsets: - * the add set for elements to be added and the remove set for elements to be removed. + * Last-Write-Wins Element Set (LWWElementSet) is a state-based CRDT (Conflict-free Replicated Data + * Type) designed for managing sets in a distributed and concurrent environment. It supports the + * addition and removal of elements, using timestamps to determine the order of operations. The set + * is split into two subsets: the add set for elements to be added and the remove set for elements + * to be removed. The LWWElementSet ensures that the most recent operation (based on the timestamp) + * wins in the case of concurrent operations. * - * @author itakurah (Niklas Hoefflin) (https://github.com/itakurah) - * @see Conflict-free_replicated_data_type - * @see itakurah (Niklas Hoefflin) + * @param The type of the elements in the LWWElementSet. + * @author itakurah (GitHub), Niklas Hoefflin (LinkedIn) + * @see Conflict free + * replicated data type (Wikipedia) + * @see A comprehensive study of + * Convergent and Commutative Replicated Data Types */ - -class Element { - String key; - int timestamp; - Bias bias; +class LWWElementSet { + final Map> addSet; + final Map> removeSet; /** - * Constructs a new Element with the specified key, timestamp and bias. - * - * @param key The key of the element. - * @param timestamp The timestamp associated with the element. - * @param bias The bias of the element (ADDS or REMOVALS). - */ - Element(String key, int timestamp, Bias bias) { - this.key = key; - this.timestamp = timestamp; - this.bias = bias; - } -} - -enum Bias { - /** - * ADDS bias for the add set. - * REMOVALS bias for the remove set. - */ - ADDS, - REMOVALS -} - -class LWWElementSet { - private final Map addSet; - private final Map removeSet; - - /** - * Constructs an empty LWWElementSet. + * Constructs an empty LWWElementSet. This constructor initializes the addSet and removeSet as + * empty HashMaps. The addSet stores elements that are added, and the removeSet stores elements + * that are removed. */ LWWElementSet() { this.addSet = new HashMap<>(); @@ -55,84 +35,92 @@ class LWWElementSet { } /** - * Adds an element to the addSet. + * Adds an element to the addSet with the current timestamp. This method stores the element in the + * addSet, ensuring that the element is added to the set with an associated timestamp that + * represents the time of the addition. * - * @param e The element to be added. + * @param key The key of the element to be added. */ - public void add(Element e) { - addSet.put(e.key, e); + public void add(T key) { + addSet.put(key, new Element<>(key, Instant.now())); } /** - * Removes an element from the removeSet. + * Removes an element by adding it to the removeSet with the current timestamp. This method adds + * the element to the removeSet, marking it as removed with the current timestamp. * - * @param e The element to be removed. + * @param key The key of the element to be removed. */ - public void remove(Element e) { - if (lookup(e)) { - removeSet.put(e.key, e); - } + public void remove(T key) { + removeSet.put(key, new Element<>(key, Instant.now())); } /** - * Checks if an element is in the LWWElementSet by comparing timestamps in the addSet and removeSet. + * Checks if an element is in the LWWElementSet. An element is considered present if it exists in + * the addSet and either does not exist in the removeSet, or its add timestamp is later than any + * corresponding remove timestamp. * - * @param e The element to be checked. - * @return True if the element is present, false otherwise. + * @param key The key of the element to be checked. + * @return {@code true} if the element is present in the set (i.e., its add timestamp is later + * than its remove timestamp, or it is not in the remove set), {@code false} otherwise (i.e., + * the element has been removed or its remove timestamp is later than its add timestamp). */ - public boolean lookup(Element e) { - Element inAddSet = addSet.get(e.key); - Element inRemoveSet = removeSet.get(e.key); + public boolean lookup(T key) { + Element inAddSet = addSet.get(key); + Element inRemoveSet = removeSet.get(key); - return (inAddSet != null && (inRemoveSet == null || inAddSet.timestamp > inRemoveSet.timestamp)); + return inAddSet != null && (inRemoveSet == null || inAddSet.timestamp.isAfter(inRemoveSet.timestamp)); } /** - * Compares the LWWElementSet with another LWWElementSet to check if addSet and removeSet are a subset. + * Merges another LWWElementSet into this set. This method takes the union of both the add-sets + * and remove-sets from the two sets, resolving conflicts by keeping the element with the latest + * timestamp. If an element appears in both the add-set and remove-set of both sets, the one with + * the later timestamp will be retained. * - * @param other The LWWElementSet to compare. - * @return True if the set is subset, false otherwise. + * @param other The LWWElementSet to merge with the current set. */ - public boolean compare(LWWElementSet other) { - return other.addSet.keySet().containsAll(addSet.keySet()) && other.removeSet.keySet().containsAll(removeSet.keySet()); + public void merge(LWWElementSet other) { + for (Map.Entry> entry : other.addSet.entrySet()) { + addSet.merge(entry.getKey(), entry.getValue(), this::resolveConflict); + } + for (Map.Entry> entry : other.removeSet.entrySet()) { + removeSet.merge(entry.getKey(), entry.getValue(), this::resolveConflict); + } } /** - * Merges another LWWElementSet into this set by resolving conflicts based on timestamps. + * Resolves conflicts between two elements by selecting the one with the later timestamp. This + * method is used when merging two LWWElementSets to ensure that the most recent operation (based + * on timestamps) is kept. * - * @param other The LWWElementSet to merge. + * @param e1 The first element. + * @param e2 The second element. + * @return The element with the later timestamp. */ - public void merge(LWWElementSet other) { - for (Element e : other.addSet.values()) { - if (!addSet.containsKey(e.key) || compareTimestamps(addSet.get(e.key), e)) { - addSet.put(e.key, e); - } - } - - for (Element e : other.removeSet.values()) { - if (!removeSet.containsKey(e.key) || compareTimestamps(removeSet.get(e.key), e)) { - removeSet.put(e.key, e); - } - } + private Element resolveConflict(Element e1, Element e2) { + return e1.timestamp.isAfter(e2.timestamp) ? e1 : e2; } +} + +/** + * Represents an element in the LWWElementSet, consisting of a key and a timestamp. This class is + * used to store the elements in both the add and remove sets with their respective timestamps. + * + * @param The type of the key associated with the element. + */ +class Element { + T key; + Instant timestamp; /** - * Compares timestamps of two elements based on their bias (ADDS or REMOVALS). + * Constructs a new Element with the specified key and timestamp. * - * @param e The first element. - * @param other The second element. - * @return True if the first element's timestamp is greater or the bias is ADDS and timestamps are equal. + * @param key The key of the element. + * @param timestamp The timestamp associated with the element. */ - public boolean compareTimestamps(Element e, Element other) { - if (e.bias != other.bias) { - throw new IllegalArgumentException("Invalid bias value"); - } - Bias bias = e.bias; - int timestampComparison = Integer.compare(e.timestamp, other.timestamp); - - if (timestampComparison == 0) { - return bias != Bias.ADDS; - } - return timestampComparison < 0; + Element(T key, Instant timestamp) { + this.key = key; + this.timestamp = timestamp; } } diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java index 36593d6669f8..0356949a8f69 100644 --- a/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java +++ b/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java @@ -3,106 +3,96 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.BeforeEach; +import java.time.Instant; import org.junit.jupiter.api.Test; class LWWElementSetTest { - private LWWElementSet set; - private final Bias bias = Bias.ADDS; - - @BeforeEach - void setUp() { - set = new LWWElementSet(); - } - @Test - void testAdd() { - Element element = new Element("key1", 1, bias); - set.add(element); - - assertTrue(set.lookup(element)); + void testAddElement() { + LWWElementSet set = new LWWElementSet<>(); + set.add("A"); + assertTrue(set.lookup("A")); } @Test - void testRemove() { - Element element = new Element("key1", 1, bias); - set.add(element); - set.remove(element); - - assertFalse(set.lookup(element)); + void testRemoveElement() { + LWWElementSet set = new LWWElementSet<>(); + set.add("A"); + set.remove("A"); + assertFalse(set.lookup("A")); } @Test - void testRemoveNonexistentElement() { - Element element = new Element("key1", 1, bias); - set.remove(element); - - assertFalse(set.lookup(element)); + void testLookupWithoutAdding() { + LWWElementSet set = new LWWElementSet<>(); + assertFalse(set.lookup("A")); } @Test - void testLookupNonexistentElement() { - Element element = new Element("key1", 1, bias); + void testLookupLaterTimestampsFalse() { + LWWElementSet set = new LWWElementSet<>(); + + set.addSet.put("A", new Element<>("A", Instant.now())); + set.removeSet.put("A", new Element<>("A", Instant.now().plusSeconds(10))); - assertFalse(set.lookup(element)); + assertFalse(set.lookup("A")); } @Test - void testCompareEqualSets() { - LWWElementSet otherSet = new LWWElementSet(); + void testLookupEarlierTimestampsTrue() { + LWWElementSet set = new LWWElementSet<>(); - Element element = new Element("key1", 1, bias); - set.add(element); - otherSet.add(element); + set.addSet.put("A", new Element<>("A", Instant.now())); + set.removeSet.put("A", new Element<>("A", Instant.now().minusSeconds(10))); - assertTrue(set.compare(otherSet)); - - otherSet.add(new Element("key2", 2, bias)); - assertTrue(set.compare(otherSet)); + assertTrue(set.lookup("A")); } @Test - void testCompareDifferentSets() { - LWWElementSet otherSet = new LWWElementSet(); - - Element element1 = new Element("key1", 1, bias); - Element element2 = new Element("key2", 2, bias); - - set.add(element1); - otherSet.add(element2); - - assertFalse(set.compare(otherSet)); + void testLookupWithConcurrentTimestamps() { + LWWElementSet set = new LWWElementSet<>(); + Instant now = Instant.now(); + set.addSet.put("A", new Element<>("A", now)); + set.removeSet.put("A", new Element<>("A", now)); + assertFalse(set.lookup("A")); } @Test - void testMerge() { - LWWElementSet otherSet = new LWWElementSet(); + void testMergeTwoSets() { + LWWElementSet set1 = new LWWElementSet<>(); + LWWElementSet set2 = new LWWElementSet<>(); - Element element1 = new Element("key1", 1, bias); - Element element2 = new Element("key2", 2, bias); + set1.add("A"); + set2.add("B"); + set2.remove("A"); - set.add(element1); - otherSet.add(element2); + set1.merge(set2); - set.merge(otherSet); - - assertTrue(set.lookup(element1)); - assertTrue(set.lookup(element2)); + assertFalse(set1.lookup("A")); + assertTrue(set1.lookup("B")); } @Test - void testCompareTimestampsEqualTimestamps() { - LWWElementSet lwwElementSet = new LWWElementSet(); + void testMergeWithConflictingTimestamps() { + LWWElementSet set1 = new LWWElementSet<>(); + LWWElementSet set2 = new LWWElementSet<>(); - Element e1 = new Element("key1", 10, Bias.REMOVALS); - Element e2 = new Element("key1", 10, Bias.REMOVALS); + Instant now = Instant.now(); + set1.addSet.put("A", new Element<>("A", now.minusSeconds(10))); + set2.addSet.put("A", new Element<>("A", now)); - assertTrue(lwwElementSet.compareTimestamps(e1, e2)); + set1.merge(set2); - e1 = new Element("key1", 10, Bias.ADDS); - e2 = new Element("key1", 10, Bias.ADDS); + assertTrue(set1.lookup("A")); + } - assertFalse(lwwElementSet.compareTimestamps(e1, e2)); + @Test + void testRemoveOlderThanAdd() { + LWWElementSet set = new LWWElementSet<>(); + Instant now = Instant.now(); + set.addSet.put("A", new Element<>("A", now)); + set.removeSet.put("A", new Element<>("A", now.minusSeconds(10))); + assertTrue(set.lookup("A")); } } From 5be5e35d2d1f2915e47da4bf8d0b41f4962d3c4d Mon Sep 17 00:00:00 2001 From: Nithin U <106614289+NithinU2802@users.noreply.github.com> Date: Mon, 17 Feb 2025 20:25:06 +0530 Subject: [PATCH 035/146] Add Heavy-Light Decomposition (HLD) (#6169) --- DIRECTORY.md | 4 + .../tree/HeavyLightDecomposition.java | 157 ++++++++++++++++++ .../tree/HeavyLightDecompositionTest.java | 69 ++++++++ 3 files changed, 230 insertions(+) create mode 100644 src/main/java/com/thealgorithms/tree/HeavyLightDecomposition.java create mode 100644 src/test/java/com/thealgorithms/tree/HeavyLightDecompositionTest.java diff --git a/DIRECTORY.md b/DIRECTORY.md index 6ccaf0b38e7f..009de2044421 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -723,6 +723,8 @@ * [WordLadder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/WordLadder.java) * zigZagPattern * [ZigZagPattern](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/zigZagPattern/ZigZagPattern.java) + * tree + * [HeavyLightDecomposition](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/tree/HeavyLightDecomposition.java) * test * java * com @@ -1367,3 +1369,5 @@ * [WordLadderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/WordLadderTest.java) * zigZagPattern * [ZigZagPatternTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/zigZagPattern/ZigZagPatternTest.java) + * tree + * [HeavyLightDecompositionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/tree/HeavyLightDecompositionTest.java) diff --git a/src/main/java/com/thealgorithms/tree/HeavyLightDecomposition.java b/src/main/java/com/thealgorithms/tree/HeavyLightDecomposition.java new file mode 100644 index 000000000000..236a23205180 --- /dev/null +++ b/src/main/java/com/thealgorithms/tree/HeavyLightDecomposition.java @@ -0,0 +1,157 @@ +package com.thealgorithms.tree; + +import java.util.ArrayList; +import java.util.List; + +/** + * Heavy-Light Decomposition (HLD) implementation in Java. + * HLD is used to efficiently handle path queries on trees, such as maximum, + * sum, or updates. It decomposes the tree into heavy and light chains, + * enabling queries in O(log N) time. + * Wikipedia Reference: https://en.wikipedia.org/wiki/Heavy-light_decomposition + * Author: Nithin U. + * Github: https://github.com/NithinU2802 + */ + +public class HeavyLightDecomposition { + private List> tree; + private int[] parent; + private int[] depth; + private int[] subtreeSize; + private int[] chainHead; + private int[] position; + private int[] nodeValue; + private int[] segmentTree; + private int positionIndex; + + public HeavyLightDecomposition(int n) { + tree = new ArrayList<>(); + for (int i = 0; i <= n; i++) { + tree.add(new ArrayList<>()); + } + parent = new int[n + 1]; + depth = new int[n + 1]; + subtreeSize = new int[n + 1]; + chainHead = new int[n + 1]; + position = new int[n + 1]; + nodeValue = new int[n + 1]; + segmentTree = new int[4 * (n + 1)]; + for (int i = 0; i <= n; i++) { + chainHead[i] = -1; + } + positionIndex = 0; + } + + public int getPosition(int index) { + return position[index]; + } + + public int getPositionIndex() { + return positionIndex; + } + + public void addEdge(int u, int v) { + tree.get(u).add(v); + tree.get(v).add(u); + } + + private void dfsSize(int node, int parentNode) { + parent[node] = parentNode; + subtreeSize[node] = 1; + for (int child : tree.get(node)) { + if (child != parentNode) { + depth[child] = depth[node] + 1; + dfsSize(child, node); + subtreeSize[node] += subtreeSize[child]; + } + } + } + + private void decompose(int node, int head) { + chainHead[node] = head; + position[node] = positionIndex++; + int heavyChild = -1; + int maxSubtreeSize = -1; + for (int child : tree.get(node)) { + if (child != parent[node] && subtreeSize[child] > maxSubtreeSize) { + heavyChild = child; + maxSubtreeSize = subtreeSize[child]; + } + } + if (heavyChild != -1) { + decompose(heavyChild, head); + } + for (int child : tree.get(node)) { + if (child != parent[node] && child != heavyChild) { + decompose(child, child); + } + } + } + + private void buildSegmentTree(int node, int start, int end) { + if (start == end) { + segmentTree[node] = nodeValue[start]; + return; + } + int mid = (start + end) / 2; + buildSegmentTree(2 * node, start, mid); + buildSegmentTree(2 * node + 1, mid + 1, end); + segmentTree[node] = Math.max(segmentTree[2 * node], segmentTree[2 * node + 1]); + } + + public void updateSegmentTree(int node, int start, int end, int index, int value) { + if (start == end) { + segmentTree[node] = value; + return; + } + int mid = (start + end) / 2; + if (index <= mid) { + updateSegmentTree(2 * node, start, mid, index, value); + } else { + updateSegmentTree(2 * node + 1, mid + 1, end, index, value); + } + segmentTree[node] = Math.max(segmentTree[2 * node], segmentTree[2 * node + 1]); + } + + public int querySegmentTree(int node, int start, int end, int left, int right) { + if (left > end || right < start) { + return Integer.MIN_VALUE; + } + if (left <= start && end <= right) { + return segmentTree[node]; + } + int mid = (start + end) / 2; + int leftQuery = querySegmentTree(2 * node, start, mid, left, right); + int rightQuery = querySegmentTree(2 * node + 1, mid + 1, end, left, right); + return Math.max(leftQuery, rightQuery); + } + + public int queryMaxInPath(int u, int v) { + int result = Integer.MIN_VALUE; + while (chainHead[u] != chainHead[v]) { + if (depth[chainHead[u]] < depth[chainHead[v]]) { + int temp = u; + u = v; + v = temp; + } + result = Math.max(result, querySegmentTree(1, 0, positionIndex - 1, position[chainHead[u]], position[u])); + u = parent[chainHead[u]]; + } + if (depth[u] > depth[v]) { + int temp = u; + u = v; + v = temp; + } + result = Math.max(result, querySegmentTree(1, 0, positionIndex - 1, position[u], position[v])); + return result; + } + + public void initialize(int root, int[] values) { + dfsSize(root, -1); + decompose(root, root); + for (int i = 0; i < values.length; i++) { + nodeValue[position[i]] = values[i]; + } + buildSegmentTree(1, 0, positionIndex - 1); + } +} diff --git a/src/test/java/com/thealgorithms/tree/HeavyLightDecompositionTest.java b/src/test/java/com/thealgorithms/tree/HeavyLightDecompositionTest.java new file mode 100644 index 000000000000..29189290e1d4 --- /dev/null +++ b/src/test/java/com/thealgorithms/tree/HeavyLightDecompositionTest.java @@ -0,0 +1,69 @@ +package com.thealgorithms.tree; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class HeavyLightDecompositionTest { + + private HeavyLightDecomposition hld; + private final int[] values = {0, 10, 20, 30, 40, 50}; + + /** + * Initializes the test environment with a predefined tree structure and values. + */ + @BeforeEach + void setUp() { + hld = new HeavyLightDecomposition(5); + hld.addEdge(1, 2); + hld.addEdge(1, 3); + hld.addEdge(2, 4); + hld.addEdge(2, 5); + hld.initialize(1, values); + } + + /** + * Verifies that the tree initializes successfully without errors. + */ + @Test + void testBasicTreeInitialization() { + assertTrue(true, "Basic tree structure initialized successfully"); + } + + /** + * Tests the maximum value query in the path between nodes. + */ + @Test + void testQueryMaxInPath() { + assertEquals(50, hld.queryMaxInPath(4, 5), "Max value in path (4,5) should be 50"); + assertEquals(30, hld.queryMaxInPath(3, 2), "Max value in path (3,2) should be 30"); + } + + /** + * Tests updating a node's value and ensuring it is reflected in queries. + */ + @Test + void testUpdateNodeValue() { + hld.updateSegmentTree(1, 0, hld.getPositionIndex() - 1, hld.getPosition(4), 100); + assertEquals(100, hld.queryMaxInPath(4, 5), "Updated value should be reflected in query"); + } + + /** + * Tests the maximum value query in a skewed tree structure. + */ + @Test + void testSkewedTreeMaxQuery() { + assertEquals(40, hld.queryMaxInPath(1, 4), "Max value in skewed tree (1,4) should be 40"); + } + + /** + * Ensures query handles cases where u is a deeper node correctly. + */ + @Test + void testDepthSwapInPathQuery() { + assertEquals(50, hld.queryMaxInPath(5, 2), "Query should handle depth swap correctly"); + assertEquals(40, hld.queryMaxInPath(4, 1), "Query should handle swapped nodes correctly and return max value"); + } +} From 1f951c1ed5dbd43e9ced6245df55740946a741de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 23:42:16 +0100 Subject: [PATCH 036/146] Bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.6.6 to 4.9.1.0 (#6171) * Bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.6.6 to 4.9.1.0 Bumps [com.github.spotbugs:spotbugs-maven-plugin](https://github.com/spotbugs/spotbugs-maven-plugin) from 4.8.6.6 to 4.9.1.0. - [Release notes](https://github.com/spotbugs/spotbugs-maven-plugin/releases) - [Commits](https://github.com/spotbugs/spotbugs-maven-plugin/compare/spotbugs-maven-plugin-4.8.6.6...spotbugs-maven-plugin-4.9.1.0) --- updated-dependencies: - dependency-name: com.github.spotbugs:spotbugs-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * fix: suppress `AT_STALE_THREAD_WRITE_OF_PRIMITIVE` --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: vil02 <65706193+vil02@users.noreply.github.com> --- pom.xml | 2 +- spotbugs-exclude.xml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7900c6f2d956..4c17a883ec24 100644 --- a/pom.xml +++ b/pom.xml @@ -132,7 +132,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.8.6.6 + 4.9.1.0 spotbugs-exclude.xml true diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml index d3eff458ea45..3b77ced1a13e 100644 --- a/spotbugs-exclude.xml +++ b/spotbugs-exclude.xml @@ -83,6 +83,9 @@ + + + From ed3680b8807853947b2e1b913fc4e9055b8335db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 22 Feb 2025 00:11:43 +0100 Subject: [PATCH 037/146] Bump org.apache.maven.plugins:maven-compiler-plugin from 3.13.0 to 3.14.0 (#6175) Bump org.apache.maven.plugins:maven-compiler-plugin Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.13.0 to 3.14.0. - [Release notes](https://github.com/apache/maven-compiler-plugin/releases) - [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.13.0...maven-compiler-plugin-3.14.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-compiler-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4c17a883ec24..e5357dec7e36 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.13.0 + 3.14.0 21 21 From bb0bb03b62021ade7c15224440accb4ceeb3feb0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 22 Feb 2025 19:52:33 +0100 Subject: [PATCH 038/146] Bump org.junit.jupiter:junit-jupiter from 5.11.4 to 5.12.0 (#6176) Bumps [org.junit.jupiter:junit-jupiter](https://github.com/junit-team/junit5) from 5.11.4 to 5.12.0. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.4...r5.12.0) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e5357dec7e36..125ea68e2a0f 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ org.junit.jupiter junit-jupiter - 5.11.4 + 5.12.0 test From f40330c553f52ec8f508ff5d959f76a5e452ce96 Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Sat, 22 Feb 2025 21:09:28 +0100 Subject: [PATCH 039/146] chore: use BOM to manage junit dependencies (#6178) --- pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pom.xml b/pom.xml index 125ea68e2a0f..20339583c606 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,6 @@ org.junit.jupiter junit-jupiter - 5.12.0 test @@ -51,7 +50,6 @@ org.junit.jupiter junit-jupiter-api - 5.11.4 test From 27bbc3e8101e5fe08ef88c5b53b5102289aadf43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 22 Feb 2025 20:13:39 +0000 Subject: [PATCH 040/146] Bump org.junit:junit-bom from 5.11.4 to 5.12.0 (#6174) Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.11.4 to 5.12.0. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.4...r5.12.0) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 20339583c606..ab8a5b5ab879 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ org.junit junit-bom - 5.11.4 + 5.12.0 pom import From 9ce2ff4865f12ec3b98cf7a35abb04d5e8d5f969 Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Mon, 24 Feb 2025 14:04:17 +0100 Subject: [PATCH 041/146] chore: remove explicit dependency to `junit-jupiter-api` (#6179) --- pom.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pom.xml b/pom.xml index ab8a5b5ab879..dc16d16d1b3f 100644 --- a/pom.xml +++ b/pom.xml @@ -45,13 +45,6 @@ 5.15.2 test - - - - org.junit.jupiter - junit-jupiter-api - test - org.apache.commons commons-lang3 From df6da475e2400bbf5f8d768e4ffbb85fabd95e3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 23:02:54 +0100 Subject: [PATCH 042/146] Bump com.puppycrawl.tools:checkstyle from 10.21.2 to 10.21.3 (#6181) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.21.2 to 10.21.3. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.21.2...checkstyle-10.21.3) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dc16d16d1b3f..ede44194ca16 100644 --- a/pom.xml +++ b/pom.xml @@ -116,7 +116,7 @@ com.puppycrawl.tools checkstyle - 10.21.2 + 10.21.3 From 849ab913c0d22c7d1df967b6e46eea849f3dab42 Mon Sep 17 00:00:00 2001 From: geetoormvn <52828564+geetoor-maven@users.noreply.github.com> Date: Thu, 27 Feb 2025 17:45:52 +0700 Subject: [PATCH 043/146] Add reverseUsingStringBuilder method to reverse a string (#6182) --- .../thealgorithms/strings/ReverseString.java | 21 +++++++++++++++++++ .../strings/ReverseStringTest.java | 6 ++++++ 2 files changed, 27 insertions(+) diff --git a/src/main/java/com/thealgorithms/strings/ReverseString.java b/src/main/java/com/thealgorithms/strings/ReverseString.java index 46a0494fcbb4..54a9b779e828 100644 --- a/src/main/java/com/thealgorithms/strings/ReverseString.java +++ b/src/main/java/com/thealgorithms/strings/ReverseString.java @@ -36,4 +36,25 @@ public static String reverse2(String str) { } return new String(value); } + + /** + * Reverse version 3 the given string using a StringBuilder. + * This method converts the string to a character array, + * iterates through it in reverse order, and appends each character + * to a StringBuilder. + * + * @param string The input string to be reversed. + * @return The reversed string. + */ + public static String reverse3(String string) { + if (string.isEmpty()) { + return string; + } + char[] chars = string.toCharArray(); + StringBuilder sb = new StringBuilder(); + for (int i = string.length() - 1; i >= 0; i--) { + sb.append(chars[i]); + } + return sb.toString(); + } } diff --git a/src/test/java/com/thealgorithms/strings/ReverseStringTest.java b/src/test/java/com/thealgorithms/strings/ReverseStringTest.java index 501f702976ec..08f5fb586d82 100644 --- a/src/test/java/com/thealgorithms/strings/ReverseStringTest.java +++ b/src/test/java/com/thealgorithms/strings/ReverseStringTest.java @@ -25,4 +25,10 @@ public void testReverseString(String input, String expectedOutput) { public void testReverseString2(String input, String expectedOutput) { assertEquals(expectedOutput, ReverseString.reverse2(input)); } + + @ParameterizedTest + @MethodSource("testCases") + public void testReverseString3(String input, String expectedOutput) { + assertEquals(expectedOutput, ReverseString.reverse3(input)); + } } From c8281e02fbb01ab2c02170aa15337315a70ef0ab Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Sat, 1 Mar 2025 09:52:06 +0100 Subject: [PATCH 044/146] Add Maximum Weighted Matching Algorithm for Trees (#6184) --- .../graphs/UndirectedAdjacencyListGraph.java | 69 ++++++++++ .../dynamicprogramming/TreeMatching.java | 78 ++++++++++++ .../dynamicprogramming/TreeMatchingTest.java | 120 ++++++++++++++++++ 3 files changed, 267 insertions(+) create mode 100644 src/main/java/com/thealgorithms/datastructures/graphs/UndirectedAdjacencyListGraph.java create mode 100644 src/main/java/com/thealgorithms/dynamicprogramming/TreeMatching.java create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/TreeMatchingTest.java diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/UndirectedAdjacencyListGraph.java b/src/main/java/com/thealgorithms/datastructures/graphs/UndirectedAdjacencyListGraph.java new file mode 100644 index 000000000000..8aafc1ef3368 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/graphs/UndirectedAdjacencyListGraph.java @@ -0,0 +1,69 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +public class UndirectedAdjacencyListGraph { + private ArrayList> adjacencyList = new ArrayList<>(); + + /** + * Adds a new node to the graph by adding an empty HashMap for its neighbors. + * @return the index of the newly added node in the adjacency list + */ + public int addNode() { + adjacencyList.add(new HashMap<>()); + return adjacencyList.size() - 1; + } + + /** + * Adds an undirected edge between the origin node (@orig) and the destination node (@dest) with the specified weight. + * If the edge already exists, no changes are made. + * @param orig the index of the origin node + * @param dest the index of the destination node + * @param weight the weight of the edge between @orig and @dest + * @return true if the edge was successfully added, false if the edge already exists or if any node index is invalid + */ + public boolean addEdge(int orig, int dest, int weight) { + int numNodes = adjacencyList.size(); + if (orig >= numNodes || dest >= numNodes || orig < 0 || dest < 0) { + return false; + } + + if (adjacencyList.get(orig).containsKey(dest)) { + return false; + } + + adjacencyList.get(orig).put(dest, weight); + adjacencyList.get(dest).put(orig, weight); + return true; + } + + /** + * Returns the set of all adjacent nodes (neighbors) for the given node. + * @param node the index of the node whose neighbors are to be retrieved + * @return a HashSet containing the indices of all neighboring nodes + */ + public HashSet getNeighbors(int node) { + return new HashSet<>(adjacencyList.get(node).keySet()); + } + + /** + * Returns the weight of the edge between the origin node (@orig) and the destination node (@dest). + * If no edge exists, returns null. + * @param orig the index of the origin node + * @param dest the index of the destination node + * @return the weight of the edge between @orig and @dest, or null if no edge exists + */ + public Integer getEdgeWeight(int orig, int dest) { + return adjacencyList.get(orig).getOrDefault(dest, null); + } + + /** + * Returns the number of nodes currently in the graph. + * @return the number of nodes in the graph + */ + public int size() { + return adjacencyList.size(); + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/TreeMatching.java b/src/main/java/com/thealgorithms/dynamicprogramming/TreeMatching.java new file mode 100644 index 000000000000..9fd82ccaf078 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/TreeMatching.java @@ -0,0 +1,78 @@ +package com.thealgorithms.dynamicprogramming; + +import com.thealgorithms.datastructures.graphs.UndirectedAdjacencyListGraph; + +/** + * This class implements the algorithm for calculating the maximum weighted matching in a tree. + * The tree is represented as an undirected graph with weighted edges. + * + * Problem Description: + * Given an undirected tree G = (V, E) with edge weights γ: E → N and a root r ∈ V, + * the goal is to find a maximum weight matching M ⊆ E such that no two edges in M + * share a common vertex. The sum of the weights of the edges in M, ∑ e∈M γ(e), should be maximized. + * For more Information: Matching (graph theory) + * + * @author Deniz Altunkapan + */ +public class TreeMatching { + + private UndirectedAdjacencyListGraph graph; + private int[][] dp; + + /** + * Constructor that initializes the graph and the DP table. + * + * @param graph The graph that represents the tree and is used for the matching algorithm. + */ + public TreeMatching(UndirectedAdjacencyListGraph graph) { + this.graph = graph; + this.dp = new int[graph.size()][2]; + } + + /** + * Calculates the maximum weighted matching for the tree, starting from the given root node. + * + * @param root The index of the root node of the tree. + * @param parent The index of the parent node (used for recursion). + * @return The maximum weighted matching for the tree, starting from the root node. + * + */ + public int getMaxMatching(int root, int parent) { + if (root < 0 || root >= graph.size()) { + throw new IllegalArgumentException("Invalid root: " + root); + } + maxMatching(root, parent); + return Math.max(dp[root][0], dp[root][1]); + } + + /** + * Recursively computes the maximum weighted matching for a node, assuming that the node + * can either be included or excluded from the matching. + * + * @param node The index of the current node for which the matching is calculated. + * @param parent The index of the parent node (to avoid revisiting the parent node during recursion). + */ + private void maxMatching(int node, int parent) { + dp[node][0] = 0; + dp[node][1] = 0; + + int sumWithoutEdge = 0; + for (int adjNode : graph.getNeighbors(node)) { + if (adjNode == parent) { + continue; + } + maxMatching(adjNode, node); + sumWithoutEdge += Math.max(dp[adjNode][0], dp[adjNode][1]); + } + + dp[node][0] = sumWithoutEdge; + + for (int adjNode : graph.getNeighbors(node)) { + if (adjNode == parent) { + continue; + } + int weight = graph.getEdgeWeight(node, adjNode); + dp[node][1] = Math.max(dp[node][1], sumWithoutEdge - Math.max(dp[adjNode][0], dp[adjNode][1]) + dp[adjNode][0] + weight); + } + } +} diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/TreeMatchingTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/TreeMatchingTest.java new file mode 100644 index 000000000000..d5418770a5d1 --- /dev/null +++ b/src/test/java/com/thealgorithms/dynamicprogramming/TreeMatchingTest.java @@ -0,0 +1,120 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.thealgorithms.datastructures.graphs.UndirectedAdjacencyListGraph; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class TreeMatchingTest { + UndirectedAdjacencyListGraph graph; + + @BeforeEach + void setUp() { + graph = new UndirectedAdjacencyListGraph(); + for (int i = 0; i < 14; i++) { + graph.addNode(); + } + } + + @Test + void testMaxMatchingForGeneralTree() { + graph.addEdge(0, 1, 20); + graph.addEdge(0, 2, 30); + graph.addEdge(1, 3, 40); + graph.addEdge(1, 4, 10); + graph.addEdge(2, 5, 20); + graph.addEdge(3, 6, 30); + graph.addEdge(3, 7, 30); + graph.addEdge(5, 8, 40); + graph.addEdge(5, 9, 10); + + TreeMatching treeMatching = new TreeMatching(graph); + assertEquals(110, treeMatching.getMaxMatching(0, -1)); + } + + @Test + void testMaxMatchingForBalancedTree() { + graph.addEdge(0, 1, 20); + graph.addEdge(0, 2, 30); + graph.addEdge(0, 3, 40); + graph.addEdge(1, 4, 10); + graph.addEdge(1, 5, 20); + graph.addEdge(2, 6, 20); + graph.addEdge(3, 7, 30); + graph.addEdge(5, 8, 10); + graph.addEdge(5, 9, 20); + graph.addEdge(7, 10, 10); + graph.addEdge(7, 11, 10); + graph.addEdge(7, 12, 5); + TreeMatching treeMatching = new TreeMatching(graph); + assertEquals(100, treeMatching.getMaxMatching(0, -1)); + } + + @Test + void testMaxMatchingForTreeWithVariedEdgeWeights() { + graph.addEdge(0, 1, 20); + graph.addEdge(0, 2, 30); + graph.addEdge(0, 3, 40); + graph.addEdge(0, 4, 50); + graph.addEdge(1, 5, 20); + graph.addEdge(2, 6, 20); + graph.addEdge(3, 7, 30); + graph.addEdge(5, 8, 10); + graph.addEdge(5, 9, 20); + graph.addEdge(7, 10, 10); + graph.addEdge(4, 11, 50); + graph.addEdge(4, 12, 20); + TreeMatching treeMatching = new TreeMatching(graph); + assertEquals(140, treeMatching.getMaxMatching(0, -1)); + } + + @Test + void emptyTree() { + TreeMatching treeMatching = new TreeMatching(graph); + assertEquals(0, treeMatching.getMaxMatching(0, -1)); + } + + @Test + void testSingleNodeTree() { + UndirectedAdjacencyListGraph singleNodeGraph = new UndirectedAdjacencyListGraph(); + singleNodeGraph.addNode(); + + TreeMatching treeMatching = new TreeMatching(singleNodeGraph); + assertEquals(0, treeMatching.getMaxMatching(0, -1)); + } + + @Test + void testLinearTree() { + graph.addEdge(0, 1, 10); + graph.addEdge(1, 2, 20); + graph.addEdge(2, 3, 30); + graph.addEdge(3, 4, 40); + + TreeMatching treeMatching = new TreeMatching(graph); + assertEquals(60, treeMatching.getMaxMatching(0, -1)); + } + + @Test + void testStarShapedTree() { + graph.addEdge(0, 1, 15); + graph.addEdge(0, 2, 25); + graph.addEdge(0, 3, 35); + graph.addEdge(0, 4, 45); + + TreeMatching treeMatching = new TreeMatching(graph); + assertEquals(45, treeMatching.getMaxMatching(0, -1)); + } + + @Test + void testUnbalancedTree() { + graph.addEdge(0, 1, 10); + graph.addEdge(0, 2, 20); + graph.addEdge(1, 3, 30); + graph.addEdge(2, 4, 40); + graph.addEdge(4, 5, 50); + + TreeMatching treeMatching = new TreeMatching(graph); + assertEquals(100, treeMatching.getMaxMatching(0, -1)); + } +} From f70a2187aceca41327bdfff8c4b8e09096730bce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 00:37:02 +0100 Subject: [PATCH 045/146] Bump org.mockito:mockito-core from 5.15.2 to 5.16.0 (#6185) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.15.2 to 5.16.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.15.2...v5.16.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ede44194ca16..374129ed2b8f 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ org.mockito mockito-core - 5.15.2 + 5.16.0 test From b2a701a67991b39a073684e118e2144b08591319 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 00:01:18 +0100 Subject: [PATCH 046/146] Bump com.puppycrawl.tools:checkstyle from 10.21.3 to 10.21.4 (#6187) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.21.3 to 10.21.4. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.21.3...checkstyle-10.21.4) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 374129ed2b8f..0f9ab7456452 100644 --- a/pom.xml +++ b/pom.xml @@ -116,7 +116,7 @@ com.puppycrawl.tools checkstyle - 10.21.3 + 10.21.4 From 9bfc05ad8d1e4449e9c3fc9cd10320e043f8506f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 23:05:12 +0000 Subject: [PATCH 047/146] Bump com.github.spotbugs:spotbugs-maven-plugin from 4.9.1.0 to 4.9.2.0 (#6188) Bumps [com.github.spotbugs:spotbugs-maven-plugin](https://github.com/spotbugs/spotbugs-maven-plugin) from 4.9.1.0 to 4.9.2.0. - [Release notes](https://github.com/spotbugs/spotbugs-maven-plugin/releases) - [Commits](https://github.com/spotbugs/spotbugs-maven-plugin/compare/spotbugs-maven-plugin-4.9.1.0...spotbugs-maven-plugin-4.9.2.0) --- updated-dependencies: - dependency-name: com.github.spotbugs:spotbugs-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alex Klymenko --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0f9ab7456452..04073aef3d90 100644 --- a/pom.xml +++ b/pom.xml @@ -123,7 +123,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.1.0 + 4.9.2.0 spotbugs-exclude.xml true From e6073f8fefa7f1b63a9170ac56712f04469c5442 Mon Sep 17 00:00:00 2001 From: Hakim's Garage <92100853+sadiul-hakim@users.noreply.github.com> Date: Wed, 12 Mar 2025 22:35:21 +0600 Subject: [PATCH 048/146] Add math builder (#6190) --- DIRECTORY.md | 9 +- .../com/thealgorithms/maths/MathBuilder.java | 345 ++++++++++++++++++ .../matrix/PrintAMatrixInSpiralOrder.java | 9 - .../others/PrintAMatrixInSpiralOrder.java | 52 +++ .../SearchInARowAndColWiseSortedMatrix.java | 1 - .../thealgorithms/maths/MathBuilderTest.java | 38 ++ .../others/TestPrintMatrixInSpiralOrder.java | 26 ++ ...estSearchInARowAndColWiseSortedMatrix.java | 52 ++- 8 files changed, 494 insertions(+), 38 deletions(-) create mode 100644 src/main/java/com/thealgorithms/maths/MathBuilder.java create mode 100644 src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java create mode 100644 src/test/java/com/thealgorithms/maths/MathBuilderTest.java create mode 100644 src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java diff --git a/DIRECTORY.md b/DIRECTORY.md index 009de2044421..f53a6220c517 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -162,6 +162,7 @@ * [MatrixGraphs](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java) * [PrimMST](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java) * [TarjansAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java) + * [UndirectedAdjacencyListGraph](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/UndirectedAdjacencyListGraph.java) * [WelshPowell](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java) * hashmap * hashing @@ -319,6 +320,7 @@ * [SubsetSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java) * [SubsetSumSpaceOptimized](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSumSpaceOptimized.java) * [SumOfSubset](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java) + * [TreeMatching](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/TreeMatching.java) * [Tribonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java) * [UniquePaths](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java) * [UniqueSubsequencesCount](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCount.java) @@ -423,6 +425,7 @@ * [LongDivision](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LongDivision.java) * [LucasSeries](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LucasSeries.java) * [MagicSquare](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MagicSquare.java) + * [MathBuilder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MathBuilder.java) * [MaxValue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MaxValue.java) * [Means](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Means.java) * [Median](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Median.java) @@ -537,6 +540,7 @@ * [PageRank](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PageRank.java) * [PasswordGen](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PasswordGen.java) * [PerlinNoise](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PerlinNoise.java) + * [PrintAMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java) * [QueueUsingTwoStacks](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java) * [RemoveDuplicateFromString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/RemoveDuplicateFromString.java) * [ReverseStackUsingRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java) @@ -724,7 +728,7 @@ * zigZagPattern * [ZigZagPattern](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/zigZagPattern/ZigZagPattern.java) * tree - * [HeavyLightDecomposition](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/tree/HeavyLightDecomposition.java) + * [HeavyLightDecomposition](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/tree/HeavyLightDecomposition.java) * test * java * com @@ -1003,6 +1007,7 @@ * [SubsetSumSpaceOptimizedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SubsetSumSpaceOptimizedTest.java) * [SubsetSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SubsetSumTest.java) * [SumOfSubsetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java) + * [TreeMatchingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/TreeMatchingTest.java) * [TribonacciTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java) * [UniquePathsTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java) * [UniqueSubsequencesCountTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCountTest.java) @@ -1097,6 +1102,7 @@ * [LeonardoNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LeonardoNumberTest.java) * [LongDivisionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LongDivisionTest.java) * [LucasSeriesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LucasSeriesTest.java) + * [MathBuilderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MathBuilderTest.java) * [MaxValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MaxValueTest.java) * [MeansTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MeansTest.java) * [MedianTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MedianTest.java) @@ -1190,6 +1196,7 @@ * [RemoveDuplicateFromStringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/RemoveDuplicateFromStringTest.java) * [ReverseStackUsingRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ReverseStackUsingRecursionTest.java) * [SkylineProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/SkylineProblemTest.java) + * [TestPrintMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java) * [TwoPointersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TwoPointersTest.java) * [WorstFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java) * puzzlesandgames diff --git a/src/main/java/com/thealgorithms/maths/MathBuilder.java b/src/main/java/com/thealgorithms/maths/MathBuilder.java new file mode 100644 index 000000000000..3534749dd41c --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/MathBuilder.java @@ -0,0 +1,345 @@ +package com.thealgorithms.maths; + +import java.text.DecimalFormat; +import java.util.Random; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * Author: Sadiul Hakim : https://github.com/sadiul-hakim + * Profession: Backend Engineer + * Date: Oct 20, 2024 + */ +public final class MathBuilder { + private final double result; + + private MathBuilder(Builder builder) { + this.result = builder.number; + } + + // Returns final result + public double get() { + return result; + } + + // Return result in long + public long toLong() { + try { + if (Double.isNaN(result)) { + throw new IllegalArgumentException("Cannot convert NaN to long"); + } + if (result == Double.POSITIVE_INFINITY) { + return Long.MAX_VALUE; + } + if (result == Double.NEGATIVE_INFINITY) { + return Long.MIN_VALUE; + } + if (result > Long.MAX_VALUE) { + return Long.MAX_VALUE; + } + if (result < Long.MIN_VALUE) { + return Long.MIN_VALUE; + } + return Math.round(result); + } catch (Exception ex) { + return 0; + } + } + + public static class Builder { + private double number; + private double memory = 0; + + public Builder() { + number = 0; + } + + public Builder(double num) { + number = num; + } + + public Builder add(double num) { + number += num; + return this; + } + + // Takes a number and a condition, only does the operation if condition is true. + public Builder addIf(double num, BiFunction condition) { + if (condition.apply(number, num)) { + number += num; + } + return this; + } + + public Builder minus(double num) { + number -= num; + return this; + } + + // Takes a number and a condition, only does the operation if condition is true. + public Builder minusIf(double num, BiFunction condition) { + if (condition.apply(number, num)) { + number -= num; + } + return this; + } + + // Generates a random number and sets to NUMBER + public Builder rand(long seed) { + if (number != 0) { + throw new RuntimeException("Number must be zero for random assignment!"); + } + Random random = new Random(); + number = random.nextDouble(seed); + return this; + } + + // Takes PI value and sets to NUMBER + public Builder pi() { + if (number != 0) { + throw new RuntimeException("Number must be zero for PI assignment!"); + } + number = Math.PI; + return this; + } + + // Takes E value and sets to NUMBER + public Builder e() { + if (number != 0) { + throw new RuntimeException("Number must be zero for E assignment!"); + } + number = Math.E; + return this; + } + + public Builder randomInRange(double min, double max) { + + if (number != 0) { + throw new RuntimeException("Number must be zero for random assignment!"); + } + Random random = new Random(); + number = min + (max - min) * random.nextDouble(); + return this; + } + + public Builder toDegrees() { + number = Math.toDegrees(number); + return this; + } + + public Builder max(double num) { + number = Math.max(number, num); + return this; + } + + public Builder min(double num) { + number = Math.min(number, num); + return this; + } + + public Builder multiply(double num) { + number *= num; + return this; + } + + // Takes a number and a condition, only does the operation if condition is true. + public Builder multiplyIf(double num, BiFunction condition) { + if (condition.apply(number, num)) { + number *= num; + } + return this; + } + + public Builder divide(double num) { + if (num == 0) { + return this; + } + number /= num; + return this; + } + + // Takes a number and a condition, only does the operation if condition is true. + public Builder divideIf(double num, BiFunction condition) { + if (num == 0) { + return this; + } + if (condition.apply(number, num)) { + number /= num; + } + return this; + } + + public Builder mod(double num) { + number %= num; + return this; + } + + // Takes a number and a condition, only does the operation if condition is true. + public Builder modIf(double num, BiFunction condition) { + if (condition.apply(number, num)) { + number %= num; + } + return this; + } + + public Builder pow(double num) { + number = Math.pow(number, num); + return this; + } + + public Builder sqrt() { + number = Math.sqrt(number); + return this; + } + + public Builder round() { + number = Math.round(number); + return this; + } + + public Builder floor() { + number = Math.floor(number); + return this; + } + + public Builder ceil() { + number = Math.ceil(number); + return this; + } + + public Builder abs() { + number = Math.abs(number); + return this; + } + + public Builder cbrt() { + number = Math.cbrt(number); + return this; + } + + public Builder log() { + number = Math.log(number); + return this; + } + + public Builder log10() { + number = Math.log10(number); + return this; + } + + public Builder sin() { + number = Math.sin(number); + return this; + } + + public Builder cos() { + number = Math.cos(number); + return this; + } + + public Builder tan() { + number = Math.tan(number); + return this; + } + + public Builder sinh() { + number = Math.sinh(number); + return this; + } + + public Builder cosh() { + number = Math.cosh(number); + return this; + } + + public Builder tanh() { + number = Math.tanh(number); + return this; + } + + public Builder exp() { + number = Math.exp(number); + return this; + } + + public Builder toRadians() { + number = Math.toRadians(number); + return this; + } + + // Remembers the NUMBER + public Builder remember() { + memory = number; + return this; + } + + // Recalls the NUMBER + public Builder recall(boolean cleanMemory) { + number = memory; + if (cleanMemory) { + memory = 0; + } + + return this; + } + + // Recalls the NUMBER on condition + public Builder recallIf(Function condition, boolean cleanMemory) { + if (!condition.apply(number)) { + return this; + } + number = memory; + if (cleanMemory) { + memory = 0; + } + + return this; + } + + // Replaces NUMBER with given number + public Builder set(double num) { + if (number != 0) { + throw new RuntimeException("Number must be zero to set!"); + } + number = num; + return this; + } + + // Replaces NUMBER with given number on condition + public Builder setIf(double num, BiFunction condition) { + if (number != 0) { + throw new RuntimeException("Number must be zero to set!"); + } + if (condition.apply(number, num)) { + number = num; + } + return this; + } + + // Prints current NUMBER + public Builder print() { + System.out.println("MathBuilder Result :: " + number); + return this; + } + + public Builder format(String format) { + DecimalFormat formater = new DecimalFormat(format); + String num = formater.format(number); + number = Double.parseDouble(num); + return this; + } + + public Builder format(int decimalPlace) { + String pattern = "." + + "#".repeat(decimalPlace); + DecimalFormat formater = new DecimalFormat(pattern); + String num = formater.format(number); + number = Double.parseDouble(num); + return this; + } + + public MathBuilder build() { + return new MathBuilder(this); + } + } +} diff --git a/src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java b/src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java index 2e735222b7a6..2757da1f9023 100644 --- a/src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java +++ b/src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java @@ -12,7 +12,6 @@ public class PrintAMatrixInSpiralOrder { * @param col number of columns matrix has * @author Sadiul Hakim : https://github.com/sadiul-hakim */ - public List print(int[][] matrix, int row, int col) { // r traverses matrix row wise from first @@ -20,35 +19,27 @@ public List print(int[][] matrix, int row, int col) { // c traverses matrix column wise from first int c = 0; int i; - List result = new ArrayList<>(); - while (r < row && c < col) { // print first row of matrix for (i = c; i < col; i++) { result.add(matrix[r][i]); } - // increase r by one because first row printed r++; - // print last column for (i = r; i < row; i++) { result.add(matrix[i][col - 1]); } - // decrease col by one because last column has been printed col--; - // print rows from last except printed elements if (r < row) { for (i = col - 1; i >= c; i--) { result.add(matrix[row - 1][i]); } - row--; } - // print columns from first except printed elements if (c < col) { for (i = row - 1; i >= r; i--) { diff --git a/src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java b/src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java new file mode 100644 index 000000000000..abfdd006879e --- /dev/null +++ b/src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java @@ -0,0 +1,52 @@ +package com.thealgorithms.others; + +import java.util.ArrayList; +import java.util.List; + +public class PrintAMatrixInSpiralOrder { + /** + * Search a key in row and column wise sorted matrix + * + * @param matrix matrix to be searched + * @param row number of rows matrix has + * @param col number of columns matrix has + * @author Sadiul Hakim : https://github.com/sadiul-hakim + */ + public List print(int[][] matrix, int row, int col) { + // r traverses matrix row wise from first + int r = 0; + // c traverses matrix column wise from first + int c = 0; + int i; + List result = new ArrayList<>(); + while (r < row && c < col) { + // print first row of matrix + for (i = c; i < col; i++) { + result.add(matrix[r][i]); + } + // increase r by one because first row printed + r++; + // print last column + for (i = r; i < row; i++) { + result.add(matrix[i][col - 1]); + } + // decrease col by one because last column has been printed + col--; + // print rows from last except printed elements + if (r < row) { + for (i = col - 1; i >= c; i--) { + result.add(matrix[row - 1][i]); + } + row--; + } + // print columns from first except printed elements + if (c < col) { + for (i = row - 1; i >= r; i--) { + result.add(matrix[i][c]); + } + c++; + } + } + return result; + } +} diff --git a/src/main/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrix.java b/src/main/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrix.java index 91fda373dca7..b53c7e5256ca 100644 --- a/src/main/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrix.java +++ b/src/main/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrix.java @@ -15,7 +15,6 @@ public int[] search(int[][] matrix, int value) { // This variable iterates over columns int j = n - 1; int[] result = {-1, -1}; - while (i < n && j >= 0) { if (matrix[i][j] == value) { result[0] = i; diff --git a/src/test/java/com/thealgorithms/maths/MathBuilderTest.java b/src/test/java/com/thealgorithms/maths/MathBuilderTest.java new file mode 100644 index 000000000000..b6ecc6746701 --- /dev/null +++ b/src/test/java/com/thealgorithms/maths/MathBuilderTest.java @@ -0,0 +1,38 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class MathBuilderTest { + + @Test + void simpleMath() { + double result = new MathBuilder.Builder(100).add(200).multiply(10).print().divideIf(20, (a, b) -> a % 2 == 0).sqrt().print().ceil().build().get(); + assertEquals(13, result); + } + + @Test + void memoryTest() { + long result = new MathBuilder.Builder().set(100).sqrt().remember().add(21).recallIf(a -> a < 50, true).mod(2).build().toLong(); + assertEquals(0, result); + } + + @Test + void freeFallDistance() { + long distance = new MathBuilder.Builder(9.81).multiply(0.5).multiply(5 * 5).round().build().toLong(); + assertEquals(123, distance); // Expected result: 0.5 * 9.81 * 25 = 122.625 ≈ 123 + } + + @Test + void batchSalaryProcessing() { + double[] salaries = {2000, 3000, 4000, 5000}; + long[] processedSalaries = new long[salaries.length]; + for (int i = 0; i < salaries.length; i++) { + processedSalaries[i] = new MathBuilder.Builder(salaries[i]).addIf(salaries[i] * 0.1, (sal, bonus) -> sal > 2500).multiply(0.92).round().build().toLong(); + } + long[] expectedSalaries = {1840, 3036, 4048, 5060}; + assertArrayEquals(expectedSalaries, processedSalaries); + } +} diff --git a/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java b/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java new file mode 100644 index 000000000000..d35d4bb60c73 --- /dev/null +++ b/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java @@ -0,0 +1,26 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertIterableEquals; + +import java.util.List; +import org.junit.jupiter.api.Test; + +public class TestPrintMatrixInSpiralOrder { + @Test + public void testOne() { + int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; + var printClass = new PrintAMatrixInSpiralOrder(); + List res = printClass.print(matrix, matrix.length, matrix[0].length); + List list = List.of(3, 4, 5, 6, 7, 12, 18, 27, 34, 33, 32, 31, 30, 23, 14, 8, 9, 10, 11, 17, 26, 25, 24, 15, 16); + assertIterableEquals(res, list); + } + + @Test + public void testTwo() { + int[][] matrix = {{2, 2}}; + var printClass = new PrintAMatrixInSpiralOrder(); + List res = printClass.print(matrix, matrix.length, matrix[0].length); + List list = List.of(2, 2); + assertIterableEquals(res, list); + } +} diff --git a/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java b/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java index 014fb4bd24af..a56f79670cf3 100644 --- a/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java +++ b/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java @@ -1,27 +1,25 @@ -package com.thealgorithms.searches; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; - -import org.junit.jupiter.api.Test; - -public class TestSearchInARowAndColWiseSortedMatrix { - @Test - public void searchItem() { - int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; - - var test = new SearchInARowAndColWiseSortedMatrix(); - int[] res = test.search(matrix, 16); - int[] expectedResult = {2, 2}; - assertArrayEquals(expectedResult, res); - } - - @Test - public void notFound() { - int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; - - var test = new SearchInARowAndColWiseSortedMatrix(); - int[] res = test.search(matrix, 96); - int[] expectedResult = {-1, -1}; - assertArrayEquals(expectedResult, res); - } -} +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +public class TestSearchInARowAndColWiseSortedMatrix { + @Test + public void searchItem() { + int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; + var test = new SearchInARowAndColWiseSortedMatrix(); + int[] res = test.search(matrix, 16); + int[] expectedResult = {2, 2}; + assertArrayEquals(expectedResult, res); + } + + @Test + public void notFound() { + int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; + var test = new SearchInARowAndColWiseSortedMatrix(); + int[] res = test.search(matrix, 96); + int[] expectedResult = {-1, -1}; + assertArrayEquals(expectedResult, res); + } +} From 769e4975f63702a5d8f790f88c84edce18985297 Mon Sep 17 00:00:00 2001 From: Hakim's Garage <92100853+sadiul-hakim@users.noreply.github.com> Date: Sat, 15 Mar 2025 02:34:03 +0600 Subject: [PATCH 049/146] Add Parenthesis to MathBuilder (#6193) --- .../com/thealgorithms/maths/MathBuilder.java | 226 +++++++++++++++--- .../thealgorithms/maths/MathBuilderTest.java | 14 ++ 2 files changed, 206 insertions(+), 34 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/MathBuilder.java b/src/main/java/com/thealgorithms/maths/MathBuilder.java index 3534749dd41c..1cf3d8b7fc9a 100644 --- a/src/main/java/com/thealgorithms/maths/MathBuilder.java +++ b/src/main/java/com/thealgorithms/maths/MathBuilder.java @@ -26,7 +26,7 @@ public double get() { public long toLong() { try { if (Double.isNaN(result)) { - throw new IllegalArgumentException("Cannot convert NaN to long"); + throw new IllegalArgumentException("Cannot convert NaN to long!"); } if (result == Double.POSITIVE_INFINITY) { return Long.MAX_VALUE; @@ -48,6 +48,8 @@ public long toLong() { public static class Builder { private double number; + private double sideNumber; + private boolean inParenthesis; private double memory = 0; public Builder() { @@ -59,26 +61,44 @@ public Builder(double num) { } public Builder add(double num) { - number += num; + if (inParenthesis) { + sideNumber += num; + } else { + number += num; + } return this; } // Takes a number and a condition, only does the operation if condition is true. public Builder addIf(double num, BiFunction condition) { - if (condition.apply(number, num)) { + if (!condition.apply(number, num)) { + return this; + } + if (inParenthesis) { + sideNumber += num; + } else { number += num; } return this; } public Builder minus(double num) { - number -= num; + if (inParenthesis) { + sideNumber -= num; + } else { + number -= num; + } return this; } // Takes a number and a condition, only does the operation if condition is true. public Builder minusIf(double num, BiFunction condition) { - if (condition.apply(number, num)) { + if (!condition.apply(number, num)) { + return this; + } + if (inParenthesis) { + sideNumber -= num; + } else { number -= num; } return this; @@ -113,7 +133,6 @@ public Builder e() { } public Builder randomInRange(double min, double max) { - if (number != 0) { throw new RuntimeException("Number must be zero for random assignment!"); } @@ -123,28 +142,49 @@ public Builder randomInRange(double min, double max) { } public Builder toDegrees() { - number = Math.toDegrees(number); + if (inParenthesis) { + sideNumber = Math.toDegrees(sideNumber); + } else { + number = Math.toDegrees(number); + } return this; } public Builder max(double num) { - number = Math.max(number, num); + if (inParenthesis) { + sideNumber = Math.max(sideNumber, num); + } else { + number = Math.max(number, num); + } return this; } public Builder min(double num) { - number = Math.min(number, num); + if (inParenthesis) { + sideNumber = Math.min(sideNumber, num); + } else { + number = Math.min(number, num); + } return this; } public Builder multiply(double num) { - number *= num; + if (inParenthesis) { + sideNumber *= num; + } else { + number *= num; + } return this; } // Takes a number and a condition, only does the operation if condition is true. public Builder multiplyIf(double num, BiFunction condition) { - if (condition.apply(number, num)) { + if (!condition.apply(number, num)) { + return this; + } + if (inParenthesis) { + sideNumber *= num; + } else { number *= num; } return this; @@ -154,7 +194,11 @@ public Builder divide(double num) { if (num == 0) { return this; } - number /= num; + if (inParenthesis) { + sideNumber /= num; + } else { + number /= num; + } return this; } @@ -163,107 +207,189 @@ public Builder divideIf(double num, BiFunction conditio if (num == 0) { return this; } - if (condition.apply(number, num)) { + if (!condition.apply(number, num)) { + return this; + } + if (inParenthesis) { + sideNumber /= num; + } else { number /= num; } return this; } public Builder mod(double num) { - number %= num; + if (inParenthesis) { + sideNumber %= num; + } else { + number %= num; + } return this; } // Takes a number and a condition, only does the operation if condition is true. public Builder modIf(double num, BiFunction condition) { - if (condition.apply(number, num)) { + if (!condition.apply(number, num)) { + return this; + } + if (inParenthesis) { + sideNumber %= num; + } else { number %= num; } return this; } public Builder pow(double num) { - number = Math.pow(number, num); + if (inParenthesis) { + sideNumber = Math.pow(sideNumber, num); + } else { + number = Math.pow(number, num); + } return this; } public Builder sqrt() { - number = Math.sqrt(number); + if (inParenthesis) { + sideNumber = Math.sqrt(sideNumber); + } else { + number = Math.sqrt(number); + } return this; } public Builder round() { - number = Math.round(number); + if (inParenthesis) { + sideNumber = Math.round(sideNumber); + } else { + number = Math.round(number); + } return this; } public Builder floor() { - number = Math.floor(number); + if (inParenthesis) { + sideNumber = Math.floor(sideNumber); + } else { + number = Math.floor(number); + } return this; } public Builder ceil() { - number = Math.ceil(number); + if (inParenthesis) { + sideNumber = Math.ceil(sideNumber); + } else { + number = Math.ceil(number); + } return this; } public Builder abs() { - number = Math.abs(number); + if (inParenthesis) { + sideNumber = Math.abs(sideNumber); + } else { + number = Math.abs(number); + } return this; } public Builder cbrt() { - number = Math.cbrt(number); + if (inParenthesis) { + sideNumber = Math.cbrt(sideNumber); + } else { + number = Math.cbrt(number); + } return this; } public Builder log() { - number = Math.log(number); + if (inParenthesis) { + sideNumber = Math.log(sideNumber); + } else { + number = Math.log(number); + } return this; } public Builder log10() { - number = Math.log10(number); + if (inParenthesis) { + sideNumber = Math.log10(sideNumber); + } else { + number = Math.log10(number); + } return this; } public Builder sin() { - number = Math.sin(number); + if (inParenthesis) { + sideNumber = Math.sin(sideNumber); + } else { + number = Math.sin(number); + } return this; } public Builder cos() { - number = Math.cos(number); + if (inParenthesis) { + sideNumber = Math.cos(sideNumber); + } else { + number = Math.cos(number); + } return this; } public Builder tan() { - number = Math.tan(number); + if (inParenthesis) { + sideNumber = Math.tan(sideNumber); + } else { + number = Math.tan(number); + } return this; } public Builder sinh() { - number = Math.sinh(number); + if (inParenthesis) { + sideNumber = Math.sinh(sideNumber); + } else { + number = Math.sinh(number); + } return this; } public Builder cosh() { - number = Math.cosh(number); + if (inParenthesis) { + sideNumber = Math.cosh(sideNumber); + } else { + number = Math.cosh(number); + } return this; } public Builder tanh() { - number = Math.tanh(number); + if (inParenthesis) { + sideNumber = Math.tanh(sideNumber); + } else { + number = Math.tanh(number); + } return this; } public Builder exp() { - number = Math.exp(number); + if (inParenthesis) { + sideNumber = Math.exp(sideNumber); + } else { + number = Math.exp(number); + } return this; } public Builder toRadians() { - number = Math.toRadians(number); + if (inParenthesis) { + sideNumber = Math.toRadians(sideNumber); + } else { + number = Math.toRadians(number); + } return this; } @@ -279,7 +405,6 @@ public Builder recall(boolean cleanMemory) { if (cleanMemory) { memory = 0; } - return this; } @@ -292,7 +417,6 @@ public Builder recallIf(Function condition, boolean cleanMemory if (cleanMemory) { memory = 0; } - return this; } @@ -322,6 +446,40 @@ public Builder print() { return this; } + public Builder openParenthesis(double num) { + sideNumber = num; + inParenthesis = true; + return this; + } + + public Builder closeParenthesisAndPlus() { + number += sideNumber; + inParenthesis = false; + sideNumber = 0; + return this; + } + + public Builder closeParenthesisAndMinus() { + number -= sideNumber; + inParenthesis = false; + sideNumber = 0; + return this; + } + + public Builder closeParenthesisAndMultiply() { + number *= sideNumber; + inParenthesis = false; + sideNumber = 0; + return this; + } + + public Builder closeParenthesisAndDivide() { + number /= sideNumber; + inParenthesis = false; + sideNumber = 0; + return this; + } + public Builder format(String format) { DecimalFormat formater = new DecimalFormat(format); String num = formater.format(number); diff --git a/src/test/java/com/thealgorithms/maths/MathBuilderTest.java b/src/test/java/com/thealgorithms/maths/MathBuilderTest.java index b6ecc6746701..dc381bfca5d3 100644 --- a/src/test/java/com/thealgorithms/maths/MathBuilderTest.java +++ b/src/test/java/com/thealgorithms/maths/MathBuilderTest.java @@ -35,4 +35,18 @@ void batchSalaryProcessing() { long[] expectedSalaries = {1840, 3036, 4048, 5060}; assertArrayEquals(expectedSalaries, processedSalaries); } + + @Test + void parenthesis() { + // 10 + (20*5) - 40 + (100 / 10) = 80 + double result = new MathBuilder.Builder(10).openParenthesis(20).multiply(5).closeParenthesisAndPlus().minus(40).openParenthesis(100).divide(10).closeParenthesisAndPlus().build().get(); + assertEquals(80, result); + } + + @Test + void areaOfCircle() { + // Radius is 4 + double area = new MathBuilder.Builder().pi().openParenthesis(4).multiply(4).closeParenthesisAndMultiply().build().get(); + assertEquals(Math.PI * 4 * 4, area); + } } From 5285a3d7aa6013d250a8ccce7e1ebca54f0351b6 Mon Sep 17 00:00:00 2001 From: David Kong <21kondav@gmail.com> Date: Fri, 14 Mar 2025 17:57:55 -0400 Subject: [PATCH 050/146] Add a linear system solver (#6196) --- .../com/thealgorithms/matrix/SolveSystem.java | 71 +++++++++++++++++++ .../thealgorithms/matrix/SolveSystemTest.java | 21 ++++++ 2 files changed, 92 insertions(+) create mode 100644 src/main/java/com/thealgorithms/matrix/SolveSystem.java create mode 100644 src/test/java/com/thealgorithms/matrix/SolveSystemTest.java diff --git a/src/main/java/com/thealgorithms/matrix/SolveSystem.java b/src/main/java/com/thealgorithms/matrix/SolveSystem.java new file mode 100644 index 000000000000..9e683bc4dc5c --- /dev/null +++ b/src/main/java/com/thealgorithms/matrix/SolveSystem.java @@ -0,0 +1,71 @@ +package com.thealgorithms.matrix; + +/** + * This class implements an algorithm for solving a system of equations of the form Ax=b using gaussian elimination and back substitution. + * + * @link Gaussian Elimination Wiki + * @see InverseOfMatrix finds the full of inverse of a matrice, but is not required to solve a system. + */ +public final class SolveSystem { + private SolveSystem() { + } + + /** + * Problem: Given a matrix A and vector b, solve the linear system Ax = b for the vector x.\ + *

+ * This OVERWRITES the input matrix to save on memory + * + * @param matrix - a square matrix of doubles + * @param constants - an array of constant + * @return solutions + */ + public static double[] solveSystem(double[][] matrix, double[] constants) { + final double tol = 0.00000001; // tolerance for round off + for (int k = 0; k < matrix.length - 1; k++) { + // find the largest value in column (to avoid zero pivots) + double maxVal = Math.abs(matrix[k][k]); + int maxIdx = k; + for (int j = k + 1; j < matrix.length; j++) { + if (Math.abs(matrix[j][k]) > maxVal) { + maxVal = matrix[j][k]; + maxIdx = j; + } + } + if (Math.abs(maxVal) < tol) { + // hope the matrix works out + continue; + } + // swap rows + double[] temp = matrix[k]; + matrix[k] = matrix[maxIdx]; + matrix[maxIdx] = temp; + double tempConst = constants[k]; + constants[k] = constants[maxIdx]; + constants[maxIdx] = tempConst; + for (int i = k + 1; i < matrix.length; i++) { + // compute multipliers and save them in the column + matrix[i][k] /= matrix[k][k]; + for (int j = k + 1; j < matrix.length; j++) { + matrix[i][j] -= matrix[i][k] * matrix[k][j]; + } + constants[i] -= matrix[i][k] * constants[k]; + } + } + // back substitution + double[] x = new double[constants.length]; + System.arraycopy(constants, 0, x, 0, constants.length); + for (int i = matrix.length - 1; i >= 0; i--) { + double sum = 0; + for (int j = i + 1; j < matrix.length; j++) { + sum += matrix[i][j] * x[j]; + } + x[i] = constants[i] - sum; + if (Math.abs(matrix[i][i]) > tol) { + x[i] /= matrix[i][i]; + } else { + throw new IllegalArgumentException("Matrix was found to be singular"); + } + } + return x; + } +} diff --git a/src/test/java/com/thealgorithms/matrix/SolveSystemTest.java b/src/test/java/com/thealgorithms/matrix/SolveSystemTest.java new file mode 100644 index 000000000000..c8d289bd8339 --- /dev/null +++ b/src/test/java/com/thealgorithms/matrix/SolveSystemTest.java @@ -0,0 +1,21 @@ +package com.thealgorithms.matrix; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class SolveSystemTest { + + @ParameterizedTest + @MethodSource({"matrixGenerator"}) + void solveSystem(double[][] matrix, double[] constants, double[] solution) { + double[] expected = SolveSystem.solveSystem(matrix, constants); + assertArrayEquals(expected, solution, 1.0E-10, "Solution does not match expected"); + } + private static Stream matrixGenerator() { + return Stream.of(Arguments.of(new double[][] {{-5, 8, -4}, {0, 6, 3}, {0, 0, -4}}, new double[] {38, -9, 20}, new double[] {-2, 1, -5}), Arguments.of(new double[][] {{-2, -1, -1}, {3, 4, 1}, {3, 6, 5}}, new double[] {-11, 19, 43}, new double[] {2, 2, 5})); + } +} From 8509be15f0888e09af5a651e668827b21585aec0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 00:52:55 +0100 Subject: [PATCH 051/146] Bump org.junit:junit-bom from 5.12.0 to 5.12.1 (#6197) Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.12.0 to 5.12.1. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.0...r5.12.1) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 04073aef3d90..fe738d9776a4 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ org.junit junit-bom - 5.12.0 + 5.12.1 pom import From 1a69a2da156d4f1576e16f1ae6e85a59594085ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 23:23:19 +0100 Subject: [PATCH 052/146] Bump com.github.spotbugs:spotbugs-maven-plugin from 4.9.2.0 to 4.9.3.0 (#6198) Bumps [com.github.spotbugs:spotbugs-maven-plugin](https://github.com/spotbugs/spotbugs-maven-plugin) from 4.9.2.0 to 4.9.3.0. - [Release notes](https://github.com/spotbugs/spotbugs-maven-plugin/releases) - [Commits](https://github.com/spotbugs/spotbugs-maven-plugin/compare/spotbugs-maven-plugin-4.9.2.0...spotbugs-maven-plugin-4.9.3.0) --- updated-dependencies: - dependency-name: com.github.spotbugs:spotbugs-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fe738d9776a4..b757c18078bd 100644 --- a/pom.xml +++ b/pom.xml @@ -123,7 +123,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.2.0 + 4.9.3.0 spotbugs-exclude.xml true From b44ecf7ef6635e6c293ec7e8f9ad523ce4402224 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 23:28:41 +0100 Subject: [PATCH 053/146] Bump org.mockito:mockito-core from 5.16.0 to 5.16.1 (#6199) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.16.0 to 5.16.1. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.16.0...v5.16.1) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Oleksandr Klymenko --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b757c18078bd..b8ab98289244 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ org.mockito mockito-core - 5.16.0 + 5.16.1 test From 45148874e841c3b0db0a5a0d46e2871f30b0d3e0 Mon Sep 17 00:00:00 2001 From: Sufiyan Chougule <100443252+Sufi-san@users.noreply.github.com> Date: Tue, 18 Mar 2025 15:59:20 +0530 Subject: [PATCH 054/146] Add feature to convert numeric words to their number representation (#6195) --- DIRECTORY.md | 2 + .../conversions/WordsToNumber.java | 343 ++++++++++++++++++ .../conversions/WordsToNumberTest.java | 114 ++++++ 3 files changed, 459 insertions(+) create mode 100644 src/main/java/com/thealgorithms/conversions/WordsToNumber.java create mode 100644 src/test/java/com/thealgorithms/conversions/WordsToNumberTest.java diff --git a/DIRECTORY.md b/DIRECTORY.md index f53a6220c517..fe9e440da3e2 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -118,6 +118,7 @@ * [TurkishToLatinConversion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java) * [UnitConversions](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/UnitConversions.java) * [UnitsConverter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/UnitsConverter.java) + * [WordsToNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/WordsToNumber.java) * datastructures * bags * [Bag](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/bags/Bag.java) @@ -840,6 +841,7 @@ * [TurkishToLatinConversionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/TurkishToLatinConversionTest.java) * [UnitConversionsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/UnitConversionsTest.java) * [UnitsConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/UnitsConverterTest.java) + * [WordsToNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/WordsToNumberTest.java) * datastructures * bag * [BagTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/bag/BagTest.java) diff --git a/src/main/java/com/thealgorithms/conversions/WordsToNumber.java b/src/main/java/com/thealgorithms/conversions/WordsToNumber.java new file mode 100644 index 000000000000..e2b81a0f4b47 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/WordsToNumber.java @@ -0,0 +1,343 @@ +package com.thealgorithms.conversions; + +import java.io.Serial; +import java.math.BigDecimal; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + A Java-based utility for converting English word representations of numbers + into their numeric form. This utility supports whole numbers, decimals, + large values up to trillions, and even scientific notation where applicable. + It ensures accurate parsing while handling edge cases like negative numbers, + improper word placements, and ambiguous inputs. + * + */ + +public final class WordsToNumber { + + private WordsToNumber() { + } + + private enum NumberWord { + ZERO("zero", 0), + ONE("one", 1), + TWO("two", 2), + THREE("three", 3), + FOUR("four", 4), + FIVE("five", 5), + SIX("six", 6), + SEVEN("seven", 7), + EIGHT("eight", 8), + NINE("nine", 9), + TEN("ten", 10), + ELEVEN("eleven", 11), + TWELVE("twelve", 12), + THIRTEEN("thirteen", 13), + FOURTEEN("fourteen", 14), + FIFTEEN("fifteen", 15), + SIXTEEN("sixteen", 16), + SEVENTEEN("seventeen", 17), + EIGHTEEN("eighteen", 18), + NINETEEN("nineteen", 19), + TWENTY("twenty", 20), + THIRTY("thirty", 30), + FORTY("forty", 40), + FIFTY("fifty", 50), + SIXTY("sixty", 60), + SEVENTY("seventy", 70), + EIGHTY("eighty", 80), + NINETY("ninety", 90); + + private final String word; + private final int value; + + NumberWord(String word, int value) { + this.word = word; + this.value = value; + } + + public static Integer getValue(String word) { + for (NumberWord num : values()) { + if (word.equals(num.word)) { + return num.value; + } + } + return null; + } + } + + private enum PowerOfTen { + THOUSAND("thousand", new BigDecimal("1000")), + MILLION("million", new BigDecimal("1000000")), + BILLION("billion", new BigDecimal("1000000000")), + TRILLION("trillion", new BigDecimal("1000000000000")); + + private final String word; + private final BigDecimal value; + + PowerOfTen(String word, BigDecimal value) { + this.word = word; + this.value = value; + } + + public static BigDecimal getValue(String word) { + for (PowerOfTen power : values()) { + if (word.equals(power.word)) { + return power.value; + } + } + return null; + } + } + + public static String convert(String numberInWords) { + if (numberInWords == null) { + throw new WordsToNumberException(WordsToNumberException.ErrorType.NULL_INPUT, ""); + } + + ArrayDeque wordDeque = preprocessWords(numberInWords); + BigDecimal completeNumber = convertWordQueueToBigDecimal(wordDeque); + + return completeNumber.toString(); + } + + public static BigDecimal convertToBigDecimal(String numberInWords) { + String conversionResult = convert(numberInWords); + return new BigDecimal(conversionResult); + } + + private static ArrayDeque preprocessWords(String numberInWords) { + String[] wordSplitArray = numberInWords.trim().split("[ ,-]"); + ArrayDeque wordDeque = new ArrayDeque<>(); + for (String word : wordSplitArray) { + if (word.isEmpty()) { + continue; + } + wordDeque.add(word.toLowerCase()); + } + if (wordDeque.isEmpty()) { + throw new WordsToNumberException(WordsToNumberException.ErrorType.NULL_INPUT, ""); + } + return wordDeque; + } + + private static void handleConjunction(boolean prevNumWasHundred, boolean prevNumWasPowerOfTen, ArrayDeque wordDeque) { + if (wordDeque.isEmpty()) { + throw new WordsToNumberException(WordsToNumberException.ErrorType.INVALID_CONJUNCTION, ""); + } + + String nextWord = wordDeque.pollFirst(); + String afterNextWord = wordDeque.peekFirst(); + + wordDeque.addFirst(nextWord); + + Integer number = NumberWord.getValue(nextWord); + + boolean isPrevWordValid = prevNumWasHundred || prevNumWasPowerOfTen; + boolean isNextWordValid = number != null && (number >= 10 || afterNextWord == null || "point".equals(afterNextWord)); + + if (!isPrevWordValid || !isNextWordValid) { + throw new WordsToNumberException(WordsToNumberException.ErrorType.INVALID_CONJUNCTION, ""); + } + } + + private static BigDecimal handleHundred(BigDecimal currentChunk, String word, boolean prevNumWasPowerOfTen) { + boolean currentChunkIsZero = currentChunk.compareTo(BigDecimal.ZERO) == 0; + if (currentChunk.compareTo(BigDecimal.TEN) >= 0 || prevNumWasPowerOfTen) { + throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word); + } + if (currentChunkIsZero) { + currentChunk = currentChunk.add(BigDecimal.ONE); + } + return currentChunk.multiply(BigDecimal.valueOf(100)); + } + + private static void handlePowerOfTen(List chunks, BigDecimal currentChunk, BigDecimal powerOfTen, String word, boolean prevNumWasPowerOfTen) { + boolean currentChunkIsZero = currentChunk.compareTo(BigDecimal.ZERO) == 0; + if (currentChunkIsZero || prevNumWasPowerOfTen) { + throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word); + } + BigDecimal nextChunk = currentChunk.multiply(powerOfTen); + + if (!(chunks.isEmpty() || isAdditionSafe(chunks.getLast(), nextChunk))) { + throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word); + } + chunks.add(nextChunk); + } + + private static BigDecimal handleNumber(Collection chunks, BigDecimal currentChunk, String word, Integer number) { + boolean currentChunkIsZero = currentChunk.compareTo(BigDecimal.ZERO) == 0; + if (number == 0 && !(currentChunkIsZero && chunks.isEmpty())) { + throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word); + } + BigDecimal bigDecimalNumber = BigDecimal.valueOf(number); + + if (!currentChunkIsZero && !isAdditionSafe(currentChunk, bigDecimalNumber)) { + throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD, word); + } + return currentChunk.add(bigDecimalNumber); + } + + private static void handlePoint(Collection chunks, BigDecimal currentChunk, ArrayDeque wordDeque) { + boolean currentChunkIsZero = currentChunk.compareTo(BigDecimal.ZERO) == 0; + if (!currentChunkIsZero) { + chunks.add(currentChunk); + } + + String decimalPart = convertDecimalPart(wordDeque); + chunks.add(new BigDecimal(decimalPart)); + } + + private static void handleNegative(boolean isNegative) { + if (isNegative) { + throw new WordsToNumberException(WordsToNumberException.ErrorType.MULTIPLE_NEGATIVES, ""); + } + throw new WordsToNumberException(WordsToNumberException.ErrorType.INVALID_NEGATIVE, ""); + } + + private static BigDecimal convertWordQueueToBigDecimal(ArrayDeque wordDeque) { + BigDecimal currentChunk = BigDecimal.ZERO; + List chunks = new ArrayList<>(); + + boolean isNegative = "negative".equals(wordDeque.peek()); + if (isNegative) { + wordDeque.poll(); + } + + boolean prevNumWasHundred = false; + boolean prevNumWasPowerOfTen = false; + + while (!wordDeque.isEmpty()) { + String word = wordDeque.poll(); + + switch (word) { + case "and" -> { + handleConjunction(prevNumWasHundred, prevNumWasPowerOfTen, wordDeque); + continue; + } + case "hundred" -> { + currentChunk = handleHundred(currentChunk, word, prevNumWasPowerOfTen); + prevNumWasHundred = true; + continue; + } + default -> { + + } + } + prevNumWasHundred = false; + + BigDecimal powerOfTen = PowerOfTen.getValue(word); + if (powerOfTen != null) { + handlePowerOfTen(chunks, currentChunk, powerOfTen, word, prevNumWasPowerOfTen); + currentChunk = BigDecimal.ZERO; + prevNumWasPowerOfTen = true; + continue; + } + prevNumWasPowerOfTen = false; + + Integer number = NumberWord.getValue(word); + if (number != null) { + currentChunk = handleNumber(chunks, currentChunk, word, number); + continue; + } + + switch (word) { + case "point" -> { + handlePoint(chunks, currentChunk, wordDeque); + currentChunk = BigDecimal.ZERO; + continue; + } + case "negative" -> { + handleNegative(isNegative); + } + default -> { + + } + } + + throw new WordsToNumberException(WordsToNumberException.ErrorType.UNKNOWN_WORD, word); + } + + if (currentChunk.compareTo(BigDecimal.ZERO) != 0) { + chunks.add(currentChunk); + } + + BigDecimal completeNumber = combineChunks(chunks); + return isNegative ? completeNumber.multiply(BigDecimal.valueOf(-1)) + : + completeNumber; + } + + private static boolean isAdditionSafe(BigDecimal currentChunk, BigDecimal number) { + int chunkDigitCount = currentChunk.toString().length(); + int numberDigitCount = number.toString().length(); + return chunkDigitCount > numberDigitCount; + } + + private static String convertDecimalPart(ArrayDeque wordDeque) { + StringBuilder decimalPart = new StringBuilder("."); + + while (!wordDeque.isEmpty()) { + String word = wordDeque.poll(); + Integer number = NumberWord.getValue(word); + if (number == null) { + throw new WordsToNumberException(WordsToNumberException.ErrorType.UNEXPECTED_WORD_AFTER_POINT, word); + } + decimalPart.append(number); + } + + boolean missingNumbers = decimalPart.length() == 1; + if (missingNumbers) { + throw new WordsToNumberException(WordsToNumberException.ErrorType.MISSING_DECIMAL_NUMBERS, ""); + } + return decimalPart.toString(); + } + + private static BigDecimal combineChunks(List chunks) { + BigDecimal completeNumber = BigDecimal.ZERO; + for (BigDecimal chunk : chunks) { + completeNumber = completeNumber.add(chunk); + } + return completeNumber; + } + } + + class WordsToNumberException extends RuntimeException { + + @Serial private static final long serialVersionUID = 1L; + + enum ErrorType { + NULL_INPUT("'null' or empty input provided"), + UNKNOWN_WORD("Unknown Word: "), + UNEXPECTED_WORD("Unexpected Word: "), + UNEXPECTED_WORD_AFTER_POINT("Unexpected Word (after Point): "), + MISSING_DECIMAL_NUMBERS("Decimal part is missing numbers."), + MULTIPLE_NEGATIVES("Multiple 'Negative's detected."), + INVALID_NEGATIVE("Incorrect 'negative' placement"), + INVALID_CONJUNCTION("Incorrect 'and' placement"); + + private final String message; + + ErrorType(String message) { + this.message = message; + } + + public String formatMessage(String details) { + return "Invalid Input. " + message + (details.isEmpty() ? "" : details); + } + } + + public final ErrorType errorType; + + WordsToNumberException(ErrorType errorType, String details) { + super(errorType.formatMessage(details)); + this.errorType = errorType; + } + + public ErrorType getErrorType() { + return errorType; + } + } diff --git a/src/test/java/com/thealgorithms/conversions/WordsToNumberTest.java b/src/test/java/com/thealgorithms/conversions/WordsToNumberTest.java new file mode 100644 index 000000000000..fbf63e37946b --- /dev/null +++ b/src/test/java/com/thealgorithms/conversions/WordsToNumberTest.java @@ -0,0 +1,114 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.math.BigDecimal; +import org.junit.jupiter.api.Test; + +public class WordsToNumberTest { + + @Test + void testNullInput() { + WordsToNumberException exception = assertThrows(WordsToNumberException.class, () -> WordsToNumber.convert(null)); + assertEquals(WordsToNumberException.ErrorType.NULL_INPUT, exception.getErrorType(), "Exception should be of type NULL_INPUT"); + } + + @Test + void testStandardCases() { + assertEquals("0", WordsToNumber.convert("zero"), "'zero' should convert to '0'"); + assertEquals("5", WordsToNumber.convert("five"), "'five' should convert to '5'"); + assertEquals("21", WordsToNumber.convert("twenty one"), "'twenty one' should convert to '21'"); + assertEquals("101", WordsToNumber.convert("one hundred one"), "'one hundred' should convert to '101'"); + assertEquals("342", WordsToNumber.convert("three hundred and forty two"), "'three hundred and forty two' should convert to '342'"); + } + + @Test + void testLargeNumbers() { + assertEquals("1000000", WordsToNumber.convert("one million"), "'one million' should convert to '1000000'"); + assertEquals("1000000000", WordsToNumber.convert("one billion"), "'one billion' should convert to '1000000000'"); + assertEquals("1000000000000", WordsToNumber.convert("one trillion"), "'one trillion' should convert to '1000000000000'"); + assertEquals("999000000900999", WordsToNumber.convert("nine hundred ninety nine trillion nine hundred thousand nine hundred and ninety nine"), "'nine hundred ninety nine trillion nine hundred thousand nine hundred and ninety nine' should convert to '999000000900999'"); + } + + @Test + void testNegativeNumbers() { + assertEquals("-5", WordsToNumber.convert("negative five"), "'negative five' should convert to '-5'"); + assertEquals("-120", WordsToNumber.convert("negative one hundred and twenty"), "'negative one hundred and twenty' should convert correctly"); + } + + @Test + void testNegativeLargeNumbers() { + assertEquals("-1000000000000", WordsToNumber.convert("negative one trillion"), "'negative one trillion' should convert to '-1000000000000'"); + assertEquals("-9876543210987", WordsToNumber.convert("Negative Nine Trillion Eight Hundred Seventy Six Billion Five Hundred Forty Three Million Two Hundred Ten Thousand Nine Hundred Eighty Seven"), ""); + } + + @Test + void testDecimalNumbers() { + assertEquals("3.1415", WordsToNumber.convert("three point one four one five"), "'three point one four one five' should convert to '3.1415'"); + assertEquals("-2.718", WordsToNumber.convert("negative two point seven one eight"), "'negative two point seven one eight' should convert to '-2.718'"); + assertEquals("-1E-7", WordsToNumber.convert("negative zero point zero zero zero zero zero zero one"), "'negative zero point zero zero zero zero zero zero one' should convert to '-1E-7'"); + } + + @Test + void testLargeDecimalNumbers() { + assertEquals("1000000000.0000000001", WordsToNumber.convert("one billion point zero zero zero zero zero zero zero zero zero one"), "Tests a large whole number with a tiny fractional part"); + assertEquals("999999999999999.9999999999999", + WordsToNumber.convert("nine hundred ninety nine trillion nine hundred ninety nine billion nine hundred ninety nine million nine hundred ninety nine thousand nine hundred ninety nine point nine nine nine nine nine nine nine nine nine nine nine nine nine"), + "Tests maximum scale handling for large decimal numbers"); + assertEquals("0.505", WordsToNumber.convert("zero point five zero five"), "Tests a decimal with an internal zero, ensuring correct parsing"); + assertEquals("42.00000000000001", WordsToNumber.convert("forty two point zero zero zero zero zero zero zero zero zero zero zero zero zero one"), "Tests a decimal with leading zeros before a significant figure"); + assertEquals("7.89E-7", WordsToNumber.convert("zero point zero zero zero zero zero zero seven eight nine"), "Tests scientific notation for a small decimal with multiple digits"); + assertEquals("0.999999", WordsToNumber.convert("zero point nine nine nine nine nine nine"), "Tests a decimal close to one with multiple repeated digits"); + } + + @Test + void testCaseInsensitivity() { + assertEquals("21", WordsToNumber.convert("TWENTY-ONE"), "Uppercase should still convert correctly"); + assertEquals("-100.0001", WordsToNumber.convert("negAtiVe OnE HuNdReD, point ZeRO Zero zERo ONE"), "Mixed case should still convert correctly"); + assertEquals("-225647.00019", WordsToNumber.convert("nEgative twO HundRed, and twenty-Five thOusaNd, six huNdred Forty-Seven, Point zero zero zero One nInE")); + } + + @Test + void testInvalidInputs() { + WordsToNumberException exception; + + exception = assertThrows(WordsToNumberException.class, () -> WordsToNumber.convert("negative one hundred AlPha")); + assertEquals(WordsToNumberException.ErrorType.UNKNOWN_WORD, exception.getErrorType()); + + exception = assertThrows(WordsToNumberException.class, () -> WordsToNumber.convert("twenty thirteen")); + assertEquals(WordsToNumberException.ErrorType.UNEXPECTED_WORD, exception.getErrorType()); + + exception = assertThrows(WordsToNumberException.class, () -> WordsToNumber.convert("negative negative ten")); + assertEquals(WordsToNumberException.ErrorType.MULTIPLE_NEGATIVES, exception.getErrorType()); + + exception = assertThrows(WordsToNumberException.class, () -> WordsToNumber.convert("one hundred hundred")); + assertEquals(WordsToNumberException.ErrorType.UNEXPECTED_WORD, exception.getErrorType()); + + exception = assertThrows(WordsToNumberException.class, () -> WordsToNumber.convert("one thousand and hundred")); + assertEquals(WordsToNumberException.ErrorType.INVALID_CONJUNCTION, exception.getErrorType()); + + exception = assertThrows(WordsToNumberException.class, () -> WordsToNumber.convert("one thousand hundred")); + assertEquals(WordsToNumberException.ErrorType.UNEXPECTED_WORD, exception.getErrorType()); + + exception = assertThrows(WordsToNumberException.class, () -> WordsToNumber.convert("nine hundred and nine hundred")); + assertEquals(WordsToNumberException.ErrorType.INVALID_CONJUNCTION, exception.getErrorType()); + + exception = assertThrows(WordsToNumberException.class, () -> WordsToNumber.convert("forty two point")); + assertEquals(WordsToNumberException.ErrorType.MISSING_DECIMAL_NUMBERS, exception.getErrorType()); + + exception = assertThrows(WordsToNumberException.class, () -> WordsToNumber.convert("sixty seven point hello")); + assertEquals(WordsToNumberException.ErrorType.UNEXPECTED_WORD_AFTER_POINT, exception.getErrorType()); + + exception = assertThrows(WordsToNumberException.class, () -> WordsToNumber.convert("one negative")); + assertEquals(WordsToNumberException.ErrorType.INVALID_NEGATIVE, exception.getErrorType()); + } + + @Test + void testConvertToBigDecimal() { + assertEquals(new BigDecimal("-100000000000000.056"), WordsToNumber.convertToBigDecimal("negative one hundred trillion point zero five six"), "should convert to appropriate BigDecimal value"); + + WordsToNumberException exception = assertThrows(WordsToNumberException.class, () -> WordsToNumber.convertToBigDecimal(null)); + assertEquals(WordsToNumberException.ErrorType.NULL_INPUT, exception.getErrorType(), "Exception should be of type NULL_INPUT"); + } +} From 0072ed9aa72eefc57361f96f27db17a86b790936 Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Mon, 31 Mar 2025 19:20:58 +0200 Subject: [PATCH 055/146] style: do not suppress `lossy-conversions` (#6206) --- pom.xml | 1 - .../java/com/thealgorithms/ciphers/Caesar.java | 15 +++++++++------ .../java/com/thealgorithms/maths/AliquotSum.java | 2 +- .../com/thealgorithms/maths/PerfectNumber.java | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index b8ab98289244..43c0a2b28627 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,6 @@ -Xlint:-auxiliaryclass -Xlint:-rawtypes -Xlint:-unchecked - -Xlint:-lossy-conversions -Werror diff --git a/src/main/java/com/thealgorithms/ciphers/Caesar.java b/src/main/java/com/thealgorithms/ciphers/Caesar.java index 61c444cf6463..23535bc2b5d2 100644 --- a/src/main/java/com/thealgorithms/ciphers/Caesar.java +++ b/src/main/java/com/thealgorithms/ciphers/Caesar.java @@ -9,6 +9,9 @@ * @author khalil2535 */ public class Caesar { + private static char normalizeShift(final int shift) { + return (char) (shift % 26); + } /** * Encrypt text by shifting every Latin char by add number shift for ASCII @@ -19,7 +22,7 @@ public class Caesar { public String encode(String message, int shift) { StringBuilder encoded = new StringBuilder(); - shift %= 26; + final char shiftChar = normalizeShift(shift); final int length = message.length(); for (int i = 0; i < length; i++) { @@ -29,10 +32,10 @@ public String encode(String message, int shift) { char current = message.charAt(i); // Java law : char + int = char if (isCapitalLatinLetter(current)) { - current += shift; + current += shiftChar; encoded.append((char) (current > 'Z' ? current - 26 : current)); // 26 = number of latin letters } else if (isSmallLatinLetter(current)) { - current += shift; + current += shiftChar; encoded.append((char) (current > 'z' ? current - 26 : current)); // 26 = number of latin letters } else { encoded.append(current); @@ -50,16 +53,16 @@ public String encode(String message, int shift) { public String decode(String encryptedMessage, int shift) { StringBuilder decoded = new StringBuilder(); - shift %= 26; + final char shiftChar = normalizeShift(shift); final int length = encryptedMessage.length(); for (int i = 0; i < length; i++) { char current = encryptedMessage.charAt(i); if (isCapitalLatinLetter(current)) { - current -= shift; + current -= shiftChar; decoded.append((char) (current < 'A' ? current + 26 : current)); // 26 = number of latin letters } else if (isSmallLatinLetter(current)) { - current -= shift; + current -= shiftChar; decoded.append((char) (current < 'a' ? current + 26 : current)); // 26 = number of latin letters } else { decoded.append(current); diff --git a/src/main/java/com/thealgorithms/maths/AliquotSum.java b/src/main/java/com/thealgorithms/maths/AliquotSum.java index 0dbc58bed605..996843b56826 100644 --- a/src/main/java/com/thealgorithms/maths/AliquotSum.java +++ b/src/main/java/com/thealgorithms/maths/AliquotSum.java @@ -56,7 +56,7 @@ public static int getAliquotSum(int n) { // if n is a perfect square then its root was added twice in above loop, so subtracting root // from sum if (root == (int) root) { - sum -= root; + sum -= (int) root; } return sum; } diff --git a/src/main/java/com/thealgorithms/maths/PerfectNumber.java b/src/main/java/com/thealgorithms/maths/PerfectNumber.java index 2a935b067094..f299d08e5d27 100644 --- a/src/main/java/com/thealgorithms/maths/PerfectNumber.java +++ b/src/main/java/com/thealgorithms/maths/PerfectNumber.java @@ -63,7 +63,7 @@ public static boolean isPerfectNumber2(int n) { // if n is a perfect square then its root was added twice in above loop, so subtracting root // from sum if (root == (int) root) { - sum -= root; + sum -= (int) root; } return sum == n; From 743f9660a88df89c091ccaad5a1a05a8e4597575 Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Tue, 1 Apr 2025 00:18:19 +0200 Subject: [PATCH 056/146] Add Traveling Salesman Problem (#6205) --- .../graph/TravelingSalesman.java | 155 ++++++++++++++++++ .../graph/TravelingSalesmanTest.java | 127 ++++++++++++++ 2 files changed, 282 insertions(+) create mode 100644 src/main/java/com/thealgorithms/graph/TravelingSalesman.java create mode 100644 src/test/java/com/thealgorithms/graph/TravelingSalesmanTest.java diff --git a/src/main/java/com/thealgorithms/graph/TravelingSalesman.java b/src/main/java/com/thealgorithms/graph/TravelingSalesman.java new file mode 100644 index 000000000000..14bf89f57cf3 --- /dev/null +++ b/src/main/java/com/thealgorithms/graph/TravelingSalesman.java @@ -0,0 +1,155 @@ +package com.thealgorithms.graph; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * This class provides solutions to the Traveling Salesman Problem (TSP) using both brute-force and dynamic programming approaches. + * For more information, see Wikipedia. + * @author Deniz Altunkapan + */ + +public final class TravelingSalesman { + + // Private constructor to prevent instantiation + private TravelingSalesman() { + } + + /** + * Solves the Traveling Salesman Problem (TSP) using brute-force approach. + * This method generates all possible permutations of cities, calculates the total distance for each route, and returns the shortest distance found. + * + * @param distanceMatrix A square matrix where element [i][j] represents the distance from city i to city j. + * @return The shortest possible route distance visiting all cities exactly once and returning to the starting city. + */ + public static int bruteForce(int[][] distanceMatrix) { + if (distanceMatrix.length <= 1) { + return 0; + } + + List cities = new ArrayList<>(); + for (int i = 1; i < distanceMatrix.length; i++) { + cities.add(i); + } + + List> permutations = generatePermutations(cities); + int minDistance = Integer.MAX_VALUE; + + for (List permutation : permutations) { + List route = new ArrayList<>(); + route.add(0); + route.addAll(permutation); + int currentDistance = calculateDistance(distanceMatrix, route); + if (currentDistance < minDistance) { + minDistance = currentDistance; + } + } + + return minDistance; + } + + /** + * Computes the total distance of a given route. + * + * @param distanceMatrix A square matrix where element [i][j] represents the + * distance from city i to city j. + * @param route A list representing the order in which the cities are visited. + * @return The total distance of the route, or Integer.MAX_VALUE if the route is invalid. + */ + public static int calculateDistance(int[][] distanceMatrix, List route) { + int distance = 0; + for (int i = 0; i < route.size() - 1; i++) { + int d = distanceMatrix[route.get(i)][route.get(i + 1)]; + if (d == Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } + distance += d; + } + int returnDist = distanceMatrix[route.get(route.size() - 1)][route.get(0)]; + return (returnDist == Integer.MAX_VALUE) ? Integer.MAX_VALUE : distance + returnDist; + } + + /** + * Generates all permutations of a given list of cities. + * + * @param cities A list of cities to permute. + * @return A list of all possible permutations. + */ + private static List> generatePermutations(List cities) { + List> permutations = new ArrayList<>(); + permute(cities, 0, permutations); + return permutations; + } + + /** + * Recursively generates permutations using backtracking. + * + * @param arr The list of cities. + * @param k The current index in the permutation process. + * @param output The list to store generated permutations. + */ + private static void permute(List arr, int k, List> output) { + if (k == arr.size()) { + output.add(new ArrayList<>(arr)); + return; + } + for (int i = k; i < arr.size(); i++) { + Collections.swap(arr, i, k); + permute(arr, k + 1, output); + Collections.swap(arr, i, k); + } + } + + /** + * Solves the Traveling Salesman Problem (TSP) using dynamic programming with the Held-Karp algorithm. + * + * @param distanceMatrix A square matrix where element [i][j] represents the distance from city i to city j. + * @return The shortest possible route distance visiting all cities exactly once and returning to the starting city. + * @throws IllegalArgumentException if the input matrix is not square. + */ + public static int dynamicProgramming(int[][] distanceMatrix) { + if (distanceMatrix.length == 0) { + return 0; + } + int n = distanceMatrix.length; + + for (int[] row : distanceMatrix) { + if (row.length != n) { + throw new IllegalArgumentException("Matrix must be square"); + } + } + + int[][] dp = new int[n][1 << n]; + for (int[] row : dp) { + Arrays.fill(row, Integer.MAX_VALUE); + } + dp[0][1] = 0; + + for (int mask = 1; mask < (1 << n); mask++) { + for (int u = 0; u < n; u++) { + if ((mask & (1 << u)) == 0 || dp[u][mask] == Integer.MAX_VALUE) { + continue; + } + for (int v = 0; v < n; v++) { + if ((mask & (1 << v)) != 0 || distanceMatrix[u][v] == Integer.MAX_VALUE) { + continue; + } + int newMask = mask | (1 << v); + dp[v][newMask] = Math.min(dp[v][newMask], dp[u][mask] + distanceMatrix[u][v]); + } + } + } + + int minDistance = Integer.MAX_VALUE; + int fullMask = (1 << n) - 1; + for (int i = 1; i < n; i++) { + if (dp[i][fullMask] != Integer.MAX_VALUE && distanceMatrix[i][0] != Integer.MAX_VALUE) { + minDistance = Math.min(minDistance, dp[i][fullMask] + distanceMatrix[i][0]); + } + } + + return minDistance == Integer.MAX_VALUE ? 0 : minDistance; + } +} diff --git a/src/test/java/com/thealgorithms/graph/TravelingSalesmanTest.java b/src/test/java/com/thealgorithms/graph/TravelingSalesmanTest.java new file mode 100644 index 000000000000..b93c9f89c944 --- /dev/null +++ b/src/test/java/com/thealgorithms/graph/TravelingSalesmanTest.java @@ -0,0 +1,127 @@ +package com.thealgorithms.graph; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class TravelingSalesmanTest { + + // Test Case 1: A simple distance matrix with 4 cities + @Test + public void testBruteForceSimple() { + int[][] distanceMatrix = {{0, 10, 15, 20}, {10, 0, 35, 25}, {15, 35, 0, 30}, {20, 25, 30, 0}}; + int expectedMinDistance = 80; + int result = TravelingSalesman.bruteForce(distanceMatrix); + assertEquals(expectedMinDistance, result); + } + + @Test + public void testDynamicProgrammingSimple() { + int[][] distanceMatrix = {{0, 10, 15, 20}, {10, 0, 35, 25}, {15, 35, 0, 30}, {20, 25, 30, 0}}; + int expectedMinDistance = 80; + int result = TravelingSalesman.dynamicProgramming(distanceMatrix); + assertEquals(expectedMinDistance, result); + } + + // Test Case 2: A distance matrix with 3 cities + @Test + public void testBruteForceThreeCities() { + int[][] distanceMatrix = {{0, 10, 15}, {10, 0, 35}, {15, 35, 0}}; + int expectedMinDistance = 60; + int result = TravelingSalesman.bruteForce(distanceMatrix); + assertEquals(expectedMinDistance, result); + } + + @Test + public void testDynamicProgrammingThreeCities() { + int[][] distanceMatrix = {{0, 10, 15}, {10, 0, 35}, {15, 35, 0}}; + int expectedMinDistance = 60; + int result = TravelingSalesman.dynamicProgramming(distanceMatrix); + assertEquals(expectedMinDistance, result); + } + + // Test Case 3: A distance matrix with 5 cities (larger input) + @Test + public void testBruteForceFiveCities() { + int[][] distanceMatrix = {{0, 2, 9, 10, 1}, {2, 0, 6, 5, 8}, {9, 6, 0, 4, 3}, {10, 5, 4, 0, 7}, {1, 8, 3, 7, 0}}; + int expectedMinDistance = 15; + int result = TravelingSalesman.bruteForce(distanceMatrix); + assertEquals(expectedMinDistance, result); + } + + @Test + public void testDynamicProgrammingFiveCities() { + int[][] distanceMatrix = {{0, 2, 9, 10, 1}, {2, 0, 6, 5, 8}, {9, 6, 0, 4, 3}, {10, 5, 4, 0, 7}, {1, 8, 3, 7, 0}}; + int expectedMinDistance = 15; + int result = TravelingSalesman.dynamicProgramming(distanceMatrix); + assertEquals(expectedMinDistance, result); + } + + // Test Case 4: A distance matrix with 2 cities (simple case) + @Test + public void testBruteForceTwoCities() { + int[][] distanceMatrix = {{0, 1}, {1, 0}}; + int expectedMinDistance = 2; + int result = TravelingSalesman.bruteForce(distanceMatrix); + assertEquals(expectedMinDistance, result); + } + + @Test + public void testDynamicProgrammingTwoCities() { + int[][] distanceMatrix = {{0, 1}, {1, 0}}; + int expectedMinDistance = 2; + int result = TravelingSalesman.dynamicProgramming(distanceMatrix); + assertEquals(expectedMinDistance, result); + } + + // Test Case 5: A distance matrix with identical distances + @Test + public void testBruteForceEqualDistances() { + int[][] distanceMatrix = {{0, 10, 10, 10}, {10, 0, 10, 10}, {10, 10, 0, 10}, {10, 10, 10, 0}}; + int expectedMinDistance = 40; + int result = TravelingSalesman.bruteForce(distanceMatrix); + assertEquals(expectedMinDistance, result); + } + + @Test + public void testDynamicProgrammingEqualDistances() { + int[][] distanceMatrix = {{0, 10, 10, 10}, {10, 0, 10, 10}, {10, 10, 0, 10}, {10, 10, 10, 0}}; + int expectedMinDistance = 40; + int result = TravelingSalesman.dynamicProgramming(distanceMatrix); + assertEquals(expectedMinDistance, result); + } + + // Test Case 6: A distance matrix with only one city + @Test + public void testBruteForceOneCity() { + int[][] distanceMatrix = {{0}}; + int expectedMinDistance = 0; + int result = TravelingSalesman.bruteForce(distanceMatrix); + assertEquals(expectedMinDistance, result); + } + + @Test + public void testDynamicProgrammingOneCity() { + int[][] distanceMatrix = {{0}}; + int expectedMinDistance = 0; + int result = TravelingSalesman.dynamicProgramming(distanceMatrix); + assertEquals(expectedMinDistance, result); + } + + // Test Case 7: Distance matrix with large numbers + @Test + public void testBruteForceLargeNumbers() { + int[][] distanceMatrix = {{0, 1000000, 2000000}, {1000000, 0, 1500000}, {2000000, 1500000, 0}}; + int expectedMinDistance = 4500000; + int result = TravelingSalesman.bruteForce(distanceMatrix); + assertEquals(expectedMinDistance, result); + } + + @Test + public void testDynamicProgrammingLargeNumbers() { + int[][] distanceMatrix = {{0, 1000000, 2000000}, {1000000, 0, 1500000}, {2000000, 1500000, 0}}; + int expectedMinDistance = 4500000; + int result = TravelingSalesman.dynamicProgramming(distanceMatrix); + assertEquals(expectedMinDistance, result); + } +} From 3471bbb5a31ee729bd5a7d6e3d3993edcb598ffa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 12:10:23 +0000 Subject: [PATCH 057/146] Bump org.apache.maven.plugins:maven-surefire-plugin from 3.5.2 to 3.5.3 (#6207) Bumps [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire) from 3.5.2 to 3.5.3. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.5.2...surefire-3.5.3) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-version: 3.5.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 43c0a2b28627..104506f61b69 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ maven-surefire-plugin - 3.5.2 + 3.5.3 From a5a4873b94fbf241f73f6f95d4d40e3349ee0f66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 14:22:22 +0200 Subject: [PATCH 058/146] Bump com.puppycrawl.tools:checkstyle from 10.21.4 to 10.22.0 (#6208) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.21.4 to 10.22.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.21.4...checkstyle-10.22.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 10.22.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 104506f61b69..42abb4d7c284 100644 --- a/pom.xml +++ b/pom.xml @@ -115,7 +115,7 @@ com.puppycrawl.tools checkstyle - 10.21.4 + 10.22.0 From 22098c7d1ef06df65ccfcd33bd17d8ad9783dafc Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Tue, 1 Apr 2025 18:54:19 +0200 Subject: [PATCH 059/146] style: remove redundant PMD exclusions (#6209) --- pmd-exclude.properties | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/pmd-exclude.properties b/pmd-exclude.properties index 5bf31455e190..1848412c9d30 100644 --- a/pmd-exclude.properties +++ b/pmd-exclude.properties @@ -1,29 +1,19 @@ -com.thealgorithms.bitmanipulation.SingleBitOperations=UselessParentheses com.thealgorithms.ciphers.AffineCipher=UselessParentheses -com.thealgorithms.ciphers.ColumnarTranspositionCipher=UnnecessaryFullyQualifiedName com.thealgorithms.ciphers.DES=UselessParentheses -com.thealgorithms.ciphers.HillCipher=UselessParentheses com.thealgorithms.ciphers.RSA=UselessParentheses com.thealgorithms.conversions.AnyBaseToAnyBase=UselessParentheses com.thealgorithms.conversions.AnytoAny=UselessParentheses -com.thealgorithms.conversions.HexToOct=UselessParentheses -com.thealgorithms.conversions.IntegerToRoman=UnnecessaryFullyQualifiedName -com.thealgorithms.datastructures.crdt.LWWElementSet=UselessParentheses com.thealgorithms.datastructures.crdt.Pair=UnusedPrivateField com.thealgorithms.datastructures.graphs.AStar=UselessParentheses com.thealgorithms.datastructures.graphs.AdjacencyMatrixGraph=CollapsibleIfStatements,UnnecessaryFullyQualifiedName,UselessParentheses com.thealgorithms.datastructures.graphs.BipartiteGraphDFS=CollapsibleIfStatements -com.thealgorithms.datastructures.graphs.Kruskal=UselessParentheses com.thealgorithms.datastructures.hashmap.hashing.HashMapCuckooHashing=UselessParentheses com.thealgorithms.datastructures.heaps.FibonacciHeap=UselessParentheses -com.thealgorithms.datastructures.heaps.HeapElement=UselessParentheses com.thealgorithms.datastructures.heaps.HeapNode=UselessParentheses com.thealgorithms.datastructures.lists.DoublyLinkedList=UselessParentheses com.thealgorithms.datastructures.lists.SearchSinglyLinkedListRecursion=UselessParentheses com.thealgorithms.datastructures.lists.SinglyLinkedList=UnusedLocalVariable com.thealgorithms.datastructures.queues.PriorityQueue=UselessParentheses -com.thealgorithms.datastructures.stacks.NodeStack=UnnecessaryFullyQualifiedName,UnusedFormalParameter -com.thealgorithms.datastructures.stacks.StackArray=UselessParentheses com.thealgorithms.datastructures.trees.CheckBinaryTreeIsValidBST=UselessParentheses com.thealgorithms.datastructures.trees.SegmentTree=UselessParentheses com.thealgorithms.devutils.nodes.LargeTreeNode=UselessParentheses @@ -32,9 +22,6 @@ com.thealgorithms.devutils.nodes.SimpleTreeNode=UselessParentheses com.thealgorithms.devutils.nodes.TreeNode=UselessParentheses com.thealgorithms.divideandconquer.ClosestPair=UnnecessaryFullyQualifiedName,UselessParentheses com.thealgorithms.divideandconquer.Point=UselessParentheses -com.thealgorithms.dynamicprogramming.MatrixChainMultiplication=UselessParentheses -com.thealgorithms.dynamicprogramming.ShortestSuperSequence=UselessParentheses -com.thealgorithms.dynamicprogramming.UniquePaths=UnnecessarySemicolon com.thealgorithms.dynamicprogramming.WineProblem=UselessParentheses com.thealgorithms.maths.BinomialCoefficient=UselessParentheses com.thealgorithms.maths.Complex=UselessParentheses @@ -46,44 +33,32 @@ com.thealgorithms.maths.KaprekarNumbers=UselessParentheses com.thealgorithms.maths.KeithNumber=UselessParentheses com.thealgorithms.maths.LeonardoNumber=UselessParentheses com.thealgorithms.maths.LinearDiophantineEquationsSolver=UselessParentheses -com.thealgorithms.maths.MatrixUtil=UselessParentheses com.thealgorithms.maths.RomanNumeralUtil=UselessParentheses com.thealgorithms.maths.SecondMinMax=UselessParentheses com.thealgorithms.maths.SecondMinMaxTest=UnnecessaryFullyQualifiedName com.thealgorithms.maths.StandardDeviation=UselessParentheses com.thealgorithms.maths.SumOfArithmeticSeries=UselessParentheses com.thealgorithms.maths.TrinomialTriangle=UselessParentheses -com.thealgorithms.maths.VampireNumber=CollapsibleIfStatements com.thealgorithms.maths.Volume=UselessParentheses com.thealgorithms.misc.Sparsity=UselessParentheses -com.thealgorithms.misc.ThreeSumProblem=UselessParentheses -com.thealgorithms.misc.WordBoggle=UselessParentheses com.thealgorithms.others.CRC16=UselessParentheses com.thealgorithms.others.Damm=UnnecessaryFullyQualifiedName com.thealgorithms.others.Luhn=UnnecessaryFullyQualifiedName com.thealgorithms.others.Mandelbrot=UselessParentheses -com.thealgorithms.others.MaximumSumOfDistinctSubarraysWithLengthK=CollapsibleIfStatements com.thealgorithms.others.MiniMaxAlgorithm=UselessParentheses com.thealgorithms.others.PageRank=UselessParentheses com.thealgorithms.others.PerlinNoise=UselessParentheses com.thealgorithms.others.QueueUsingTwoStacks=UselessParentheses -com.thealgorithms.others.QueueWithStack=UselessParentheses com.thealgorithms.others.Trieac=UselessParentheses com.thealgorithms.others.Verhoeff=UnnecessaryFullyQualifiedName com.thealgorithms.searches.InterpolationSearch=UselessParentheses com.thealgorithms.searches.KMPSearch=UselessParentheses -com.thealgorithms.searches.LinearSearchThread=EmptyCatchBlock com.thealgorithms.searches.RabinKarpAlgorithm=UselessParentheses com.thealgorithms.sorts.CircleSort=EmptyControlStatement -com.thealgorithms.sorts.CombSort=UselessParentheses com.thealgorithms.sorts.DutchNationalFlagSort=UselessParentheses -com.thealgorithms.sorts.LinkListSort=EmptyControlStatement,UnusedLocalVariable com.thealgorithms.sorts.MergeSortNoExtraSpace=UselessParentheses -com.thealgorithms.sorts.PigeonholeSort=UselessParentheses com.thealgorithms.sorts.RadixSort=UselessParentheses com.thealgorithms.sorts.WiggleSort=UselessParentheses com.thealgorithms.stacks.PostfixToInfix=UselessParentheses com.thealgorithms.strings.HorspoolSearch=UnnecessaryFullyQualifiedName,UselessParentheses -com.thealgorithms.strings.MyAtoi=UselessParentheses com.thealgorithms.strings.Palindrome=UselessParentheses -com.thealgorithms.strings.Solution=CollapsibleIfStatements From 251e9e1902a11436f988228ac09877561e89063f Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Wed, 2 Apr 2025 17:51:40 +0200 Subject: [PATCH 060/146] refactor: introduce `SinglyLinkedListNode` (#6210) --- .../lists/CountSinglyLinkedListRecursion.java | 2 +- .../lists/MergeSortedSinglyLinkedList.java | 8 +- .../lists/QuickSortLinkedList.java | 20 ++-- .../datastructures/lists/ReverseKGroup.java | 20 ++-- .../lists/RotateSinglyLinkedLists.java | 4 +- .../SearchSinglyLinkedListRecursion.java | 2 +- .../lists/SinglyLinkedList.java | 102 ++++++------------ .../lists/SinglyLinkedListNode.java | 34 ++++++ .../lists/ReverseKGroupTest.java | 32 +++--- .../lists/RotateSinglyLinkedListsTest.java | 40 +++---- .../lists/SinglyLinkedListTest.java | 40 +++---- 11 files changed, 149 insertions(+), 155 deletions(-) create mode 100644 src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedListNode.java diff --git a/src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java b/src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java index 4c1ffe9d3ea4..b58d51e7e5fe 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java @@ -12,7 +12,7 @@ public class CountSinglyLinkedListRecursion extends SinglyLinkedList { * @param head the head node of the list segment being counted. * @return the count of nodes from the given head node onward. */ - private int countRecursion(Node head) { + private int countRecursion(SinglyLinkedListNode head) { return head == null ? 0 : 1 + countRecursion(head.next); } diff --git a/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java index a16b202c4505..4e99642fccd8 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java @@ -42,12 +42,12 @@ public static SinglyLinkedList merge(SinglyLinkedList listA, SinglyLinkedList li throw new NullPointerException("Input lists must not be null."); } - Node headA = listA.getHead(); - Node headB = listB.getHead(); + SinglyLinkedListNode headA = listA.getHead(); + SinglyLinkedListNode headB = listB.getHead(); int size = listA.size() + listB.size(); - Node head = new Node(); - Node tail = head; + SinglyLinkedListNode head = new SinglyLinkedListNode(); + SinglyLinkedListNode tail = head; while (headA != null && headB != null) { if (headA.value <= headB.value) { tail.next = headA; diff --git a/src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java index 08fe674b47f4..f018781ada70 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java @@ -105,7 +105,7 @@ public class QuickSortLinkedList { private final SinglyLinkedList list; // The linked list to be sorted - private Node head; // Head of the list + private SinglyLinkedListNode head; // Head of the list /** * Constructor that initializes the QuickSortLinkedList with a given linked list. @@ -136,19 +136,19 @@ public void sortList() { * @param head The head node of the list to sort * @return The head node of the sorted linked list */ - private Node sortList(Node head) { + private SinglyLinkedListNode sortList(SinglyLinkedListNode head) { if (head == null || head.next == null) { return head; } - Node pivot = head; + SinglyLinkedListNode pivot = head; head = head.next; pivot.next = null; - Node lessHead = new Node(); - Node lessTail = lessHead; - Node greaterHead = new Node(); - Node greaterTail = greaterHead; + SinglyLinkedListNode lessHead = new SinglyLinkedListNode(); + SinglyLinkedListNode lessTail = lessHead; + SinglyLinkedListNode greaterHead = new SinglyLinkedListNode(); + SinglyLinkedListNode greaterTail = greaterHead; while (head != null) { if (head.value < pivot.value) { @@ -164,14 +164,14 @@ private Node sortList(Node head) { lessTail.next = null; greaterTail.next = null; - Node sortedLess = sortList(lessHead.next); - Node sortedGreater = sortList(greaterHead.next); + SinglyLinkedListNode sortedLess = sortList(lessHead.next); + SinglyLinkedListNode sortedGreater = sortList(greaterHead.next); if (sortedLess == null) { pivot.next = sortedGreater; return pivot; } else { - Node current = sortedLess; + SinglyLinkedListNode current = sortedLess; while (current.next != null) { current = current.next; } diff --git a/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java b/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java index c9a5c1df9870..9b9464d388b5 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java @@ -14,10 +14,10 @@ *

*

* The implementation contains: - * - {@code length(Node head)}: A method to calculate the length of the linked list. - * - {@code reverse(Node head, int count, int k)}: A helper method that reverses the nodes + * - {@code length(SinglyLinkedListNode head)}: A method to calculate the length of the linked list. + * - {@code reverse(SinglyLinkedListNode head, int count, int k)}: A helper method that reverses the nodes * in the linked list in groups of k. - * - {@code reverseKGroup(Node head, int k)}: The main method that initiates the reversal + * - {@code reverseKGroup(SinglyLinkedListNode head, int k)}: The main method that initiates the reversal * process by calling the reverse method. *

*

@@ -38,8 +38,8 @@ public class ReverseKGroup { * @param head The head node of the linked list. * @return The total number of nodes in the linked list. */ - public int length(Node head) { - Node curr = head; + public int length(SinglyLinkedListNode head) { + SinglyLinkedListNode curr = head; int count = 0; while (curr != null) { curr = curr.next; @@ -56,14 +56,14 @@ public int length(Node head) { * @param k The size of the group to reverse. * @return The new head of the reversed linked list segment. */ - public Node reverse(Node head, int count, int k) { + public SinglyLinkedListNode reverse(SinglyLinkedListNode head, int count, int k) { if (count < k) { return head; } - Node prev = null; + SinglyLinkedListNode prev = null; int count1 = 0; - Node curr = head; - Node next = null; + SinglyLinkedListNode curr = head; + SinglyLinkedListNode next = null; while (curr != null && count1 < k) { next = curr.next; curr.next = prev; @@ -85,7 +85,7 @@ public Node reverse(Node head, int count, int k) { * @param k The size of the group to reverse. * @return The head of the modified linked list after reversal. */ - public Node reverseKGroup(Node head, int k) { + public SinglyLinkedListNode reverseKGroup(SinglyLinkedListNode head, int k) { int count = length(head); return reverse(head, count, k); } diff --git a/src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java b/src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java index 7676cc343653..47ee5397097c 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java @@ -38,12 +38,12 @@ public class RotateSinglyLinkedLists { * @param k The number of positions to rotate the list to the right. * @return The head of the rotated linked list. */ - public Node rotateRight(Node head, int k) { + public SinglyLinkedListNode rotateRight(SinglyLinkedListNode head, int k) { if (head == null || head.next == null || k == 0) { return head; } - Node curr = head; + SinglyLinkedListNode curr = head; int len = 1; while (curr.next != null) { curr = curr.next; diff --git a/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java b/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java index a40e9b2a1a66..4ac2de422595 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java @@ -30,7 +30,7 @@ public class SearchSinglyLinkedListRecursion extends SinglyLinkedList { * @param key the integer value to be searched for. * @return {@code true} if the value `key` is present in the list; otherwise, {@code false}. */ - private boolean searchRecursion(Node node, int key) { + private boolean searchRecursion(SinglyLinkedListNode node, int key) { return (node != null && (node.value == key || searchRecursion(node.next, key))); } diff --git a/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java index eb6cdf48f58b..ff4af4437cc7 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java @@ -12,7 +12,7 @@ public class SinglyLinkedList implements Iterable { /** * Head refer to the front of the list */ - private Node head; + private SinglyLinkedListNode head; /** * Size of SinglyLinkedList @@ -33,7 +33,7 @@ public SinglyLinkedList() { * @param head the head node of list * @param size the size of list */ - public SinglyLinkedList(Node head, int size) { + public SinglyLinkedList(SinglyLinkedListNode head, int size) { this.head = head; this.size = size; } @@ -44,8 +44,8 @@ public SinglyLinkedList(Node head, int size) { * */ public boolean detectLoop() { - Node currentNodeFast = head; - Node currentNodeSlow = head; + SinglyLinkedListNode currentNodeFast = head; + SinglyLinkedListNode currentNodeSlow = head; while (currentNodeFast != null && currentNodeFast.next != null) { currentNodeFast = currentNodeFast.next.next; currentNodeSlow = currentNodeSlow.next; @@ -61,12 +61,12 @@ public boolean detectLoop() { * If the length of the list is even then return item number length/2 * @return middle node of the list */ - public Node middle() { + public SinglyLinkedListNode middle() { if (head == null) { return null; } - Node firstCounter = head; - Node secondCounter = firstCounter.next; + SinglyLinkedListNode firstCounter = head; + SinglyLinkedListNode secondCounter = firstCounter.next; while (secondCounter != null && secondCounter.next != null) { firstCounter = firstCounter.next; secondCounter = secondCounter.next.next; @@ -82,15 +82,15 @@ public void swapNodes(int valueFirst, int valueSecond) { if (valueFirst == valueSecond) { return; } - Node previousA = null; - Node currentA = head; + SinglyLinkedListNode previousA = null; + SinglyLinkedListNode currentA = head; while (currentA != null && currentA.value != valueFirst) { previousA = currentA; currentA = currentA.next; } - Node previousB = null; - Node currentB = head; + SinglyLinkedListNode previousB = null; + SinglyLinkedListNode currentB = head; while (currentB != null && currentB.value != valueSecond) { previousB = currentB; currentB = currentB.next; @@ -117,7 +117,7 @@ public void swapNodes(int valueFirst, int valueSecond) { } // Swap next pointer - Node temp = currentA.next; + var temp = currentA.next; currentA.next = currentB.next; currentB.next = temp; } @@ -126,12 +126,12 @@ public void swapNodes(int valueFirst, int valueSecond) { * Reverse a singly linked list[Iterative] from a given node till the end * */ - public Node reverseListIter(Node node) { - Node prev = null; - Node curr = node; + public SinglyLinkedListNode reverseListIter(SinglyLinkedListNode node) { + SinglyLinkedListNode prev = null; + SinglyLinkedListNode curr = node; while (curr != null && curr.next != null) { - Node next = curr.next; + var next = curr.next; curr.next = prev; prev = curr; curr = next; @@ -149,13 +149,13 @@ public Node reverseListIter(Node node) { * Reverse a singly linked list[Recursive] from a given node till the end * */ - public Node reverseListRec(Node head) { + public SinglyLinkedListNode reverseListRec(SinglyLinkedListNode head) { if (head == null || head.next == null) { return head; } - Node prev = null; - Node h2 = reverseListRec(head.next); + SinglyLinkedListNode prev = null; + SinglyLinkedListNode h2 = reverseListRec(head.next); head.next.next = head; head.next = prev; @@ -167,7 +167,7 @@ public Node reverseListRec(Node head) { * Clear all nodes in the list */ public void clear() { - Node cur = head; + SinglyLinkedListNode cur = head; while (cur != null) { cur = cur.next; } @@ -198,7 +198,7 @@ public int size() { * * @return head of the list. */ - public Node getHead() { + public SinglyLinkedListNode getHead() { return head; } @@ -206,7 +206,7 @@ public Node getHead() { * Set head of the list. * */ - public void setHead(Node head) { + public void setHead(SinglyLinkedListNode head) { this.head = head; } @@ -249,10 +249,10 @@ public String toString() { } public void deleteDuplicates() { - Node pred = head; + SinglyLinkedListNode pred = head; // predecessor = the node // having sublist of its duplicates - Node newHead = head; + SinglyLinkedListNode newHead = head; while (newHead != null) { // if it's a beginning of duplicates sublist // skip all duplicates @@ -273,7 +273,7 @@ public void deleteDuplicates() { } public void print() { - Node temp = head; + SinglyLinkedListNode temp = head; while (temp != null && temp.next != null) { System.out.print(temp.value + "->"); temp = temp.next; @@ -310,7 +310,7 @@ public void insert(int data) { */ public void insertNth(int data, int position) { checkBounds(position, 0, size); - Node newNode = new Node(data); + SinglyLinkedListNode newNode = new SinglyLinkedListNode(data); if (head == null) { /* the list is empty */ head = newNode; @@ -325,7 +325,7 @@ public void insertNth(int data, int position) { return; } - Node cur = head; + SinglyLinkedListNode cur = head; for (int i = 0; i < position - 1; ++i) { cur = cur.next; } @@ -359,7 +359,7 @@ public void deleteNth(int position) { size--; return; } - Node cur = head; + SinglyLinkedListNode cur = head; for (int i = 0; i < position - 1; ++i) { cur = cur.next; } @@ -376,7 +376,7 @@ public void deleteNth(int position) { */ public int getNth(int index) { checkBounds(index, 0, size - 1); - Node cur = head; + SinglyLinkedListNode cur = head; for (int i = 0; i < index; ++i) { cur = cur.next; } @@ -440,7 +440,7 @@ public static void main(String[] arg) { } SinglyLinkedList instance = new SinglyLinkedList(); - Node head = new Node(0, new Node(2, new Node(3, new Node(3, new Node(4))))); + SinglyLinkedListNode head = new SinglyLinkedListNode(0, new SinglyLinkedListNode(2, new SinglyLinkedListNode(3, new SinglyLinkedListNode(3, new SinglyLinkedListNode(4))))); instance.setHead(head); instance.deleteDuplicates(); instance.print(); @@ -452,7 +452,7 @@ public Iterator iterator() { } private class SinglyLinkedListIterator implements Iterator { - private Node current; + private SinglyLinkedListNode current; SinglyLinkedListIterator() { current = head; @@ -474,43 +474,3 @@ public Integer next() { } } } - -/** - * This class is the nodes of the SinglyLinked List. They consist of a value and - * a pointer to the node after them. - */ -class Node { - - /** - * The value of the node - */ - int value; - - /** - * Point to the next node - */ - Node next; - - Node() { - } - - /** - * Constructor - * - * @param value Value to be put in the node - */ - Node(int value) { - this(value, null); - } - - /** - * Constructor - * - * @param value Value to be put in the node - * @param next Reference to the next node - */ - Node(int value, Node next) { - this.value = value; - this.next = next; - } -} diff --git a/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedListNode.java b/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedListNode.java new file mode 100644 index 000000000000..d0a06369215a --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedListNode.java @@ -0,0 +1,34 @@ +package com.thealgorithms.datastructures.lists; + +/** + * This class is the nodes of the SinglyLinked List. They consist of a value and + * a pointer to the node after them. + */ +class SinglyLinkedListNode { + + int value; + SinglyLinkedListNode next = null; + + SinglyLinkedListNode() { + } + + /** + * Constructor + * + * @param value Value to be put in the node + */ + SinglyLinkedListNode(int value) { + this(value, null); + } + + /** + * Constructor + * + * @param value Value to be put in the node + * @param next Reference to the next node + */ + SinglyLinkedListNode(int value, SinglyLinkedListNode next) { + this.value = value; + this.next = next; + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java b/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java index b2db478f692c..76b7ab063de4 100644 --- a/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java +++ b/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java @@ -20,8 +20,8 @@ public void testReverseKGroupWithEmptyList() { @Test public void testReverseKGroupWithSingleNodeList() { ReverseKGroup reverser = new ReverseKGroup(); - Node singleNode = new Node(5); - Node result = reverser.reverseKGroup(singleNode, 2); + SinglyLinkedListNode singleNode = new SinglyLinkedListNode(5); + SinglyLinkedListNode result = reverser.reverseKGroup(singleNode, 2); assertEquals(5, result.value); assertNull(result.next); } @@ -31,15 +31,15 @@ public void testReverseKGroupWithKEqualTo2() { ReverseKGroup reverser = new ReverseKGroup(); // Create a list with multiple elements (1 -> 2 -> 3 -> 4 -> 5) - Node head; - head = new Node(1); - head.next = new Node(2); - head.next.next = new Node(3); - head.next.next.next = new Node(4); - head.next.next.next.next = new Node(5); + SinglyLinkedListNode head; + head = new SinglyLinkedListNode(1); + head.next = new SinglyLinkedListNode(2); + head.next.next = new SinglyLinkedListNode(3); + head.next.next.next = new SinglyLinkedListNode(4); + head.next.next.next.next = new SinglyLinkedListNode(5); // Test reverse with k=2 - Node result1 = reverser.reverseKGroup(head, 2); + SinglyLinkedListNode result1 = reverser.reverseKGroup(head, 2); assertEquals(2, result1.value); assertEquals(1, result1.next.value); assertEquals(4, result1.next.next.value); @@ -53,15 +53,15 @@ public void testReverseKGroupWithKEqualTo3() { ReverseKGroup reverser = new ReverseKGroup(); // Create a list with multiple elements (1 -> 2 -> 3 -> 4 -> 5) - Node head; - head = new Node(1); - head.next = new Node(2); - head.next.next = new Node(3); - head.next.next.next = new Node(4); - head.next.next.next.next = new Node(5); + SinglyLinkedListNode head; + head = new SinglyLinkedListNode(1); + head.next = new SinglyLinkedListNode(2); + head.next.next = new SinglyLinkedListNode(3); + head.next.next.next = new SinglyLinkedListNode(4); + head.next.next.next.next = new SinglyLinkedListNode(5); // Test reverse with k=3 - Node result = reverser.reverseKGroup(head, 3); + SinglyLinkedListNode result = reverser.reverseKGroup(head, 3); assertEquals(3, result.value); assertEquals(2, result.next.value); assertEquals(1, result.next.next.value); diff --git a/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java b/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java index 70c0dfccafa4..c476ad1b0203 100644 --- a/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java +++ b/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java @@ -14,24 +14,24 @@ public class RotateSinglyLinkedListsTest { private final RotateSinglyLinkedLists rotator = new RotateSinglyLinkedLists(); // Helper method to create a linked list from an array of values - private Node createLinkedList(int[] values) { + private SinglyLinkedListNode createLinkedList(int[] values) { if (values.length == 0) { return null; } - Node head = new Node(values[0]); - Node current = head; + SinglyLinkedListNode head = new SinglyLinkedListNode(values[0]); + SinglyLinkedListNode current = head; for (int i = 1; i < values.length; i++) { - current.next = new Node(values[i]); + current.next = new SinglyLinkedListNode(values[i]); current = current.next; } return head; } // Helper method to convert a linked list to a string for easy comparison - private String linkedListToString(Node head) { + private String linkedListToString(SinglyLinkedListNode head) { StringBuilder sb = new StringBuilder(); - Node current = head; + SinglyLinkedListNode current = head; while (current != null) { sb.append(current.value); if (current.next != null) { @@ -51,55 +51,55 @@ public void testRotateRightEmptyList() { @Test public void testRotateRightSingleNodeList() { // Rotate a list with a single element - Node singleNode = new Node(5); - Node rotatedSingleNode = rotator.rotateRight(singleNode, 3); + SinglyLinkedListNode singleNode = new SinglyLinkedListNode(5); + SinglyLinkedListNode rotatedSingleNode = rotator.rotateRight(singleNode, 3); assertEquals("5", linkedListToString(rotatedSingleNode)); } @Test public void testRotateRightMultipleElementsList() { // Rotate a list with multiple elements (rotate by 2) - Node head = createLinkedList(new int[] {1, 2, 3, 4, 5}); - Node rotated = rotator.rotateRight(head, 2); + SinglyLinkedListNode head = createLinkedList(new int[] {1, 2, 3, 4, 5}); + SinglyLinkedListNode rotated = rotator.rotateRight(head, 2); assertEquals("4 -> 5 -> 1 -> 2 -> 3", linkedListToString(rotated)); } @Test public void testRotateRightFullRotation() { // Rotate by more than the length of the list - Node head = createLinkedList(new int[] {1, 2, 3, 4, 5}); - Node rotated = rotator.rotateRight(head, 7); + SinglyLinkedListNode head = createLinkedList(new int[] {1, 2, 3, 4, 5}); + SinglyLinkedListNode rotated = rotator.rotateRight(head, 7); assertEquals("4 -> 5 -> 1 -> 2 -> 3", linkedListToString(rotated)); } @Test public void testRotateRightZeroRotation() { // Rotate a list by k = 0 (no rotation) - Node head = createLinkedList(new int[] {1, 2, 3, 4, 5}); - Node rotated = rotator.rotateRight(head, 0); + SinglyLinkedListNode head = createLinkedList(new int[] {1, 2, 3, 4, 5}); + SinglyLinkedListNode rotated = rotator.rotateRight(head, 0); assertEquals("1 -> 2 -> 3 -> 4 -> 5", linkedListToString(rotated)); } @Test public void testRotateRightByListLength() { // Rotate a list by k equal to list length (no change) - Node head = createLinkedList(new int[] {1, 2, 3, 4, 5}); - Node rotated = rotator.rotateRight(head, 5); + SinglyLinkedListNode head = createLinkedList(new int[] {1, 2, 3, 4, 5}); + SinglyLinkedListNode rotated = rotator.rotateRight(head, 5); assertEquals("1 -> 2 -> 3 -> 4 -> 5", linkedListToString(rotated)); } @Test public void testRotateRightByMultipleOfListLength() { - Node head = createLinkedList(new int[] {1, 2, 3, 4, 5}); - Node rotated = rotator.rotateRight(head, 10); // k = 2 * list length + SinglyLinkedListNode head = createLinkedList(new int[] {1, 2, 3, 4, 5}); + SinglyLinkedListNode rotated = rotator.rotateRight(head, 10); // k = 2 * list length assertEquals("1 -> 2 -> 3 -> 4 -> 5", linkedListToString(rotated)); } @Test public void testRotateRightLongerList() { // Rotate a longer list by a smaller k - Node head = createLinkedList(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9}); - Node rotated = rotator.rotateRight(head, 4); + SinglyLinkedListNode head = createLinkedList(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9}); + SinglyLinkedListNode rotated = rotator.rotateRight(head, 4); assertEquals("6 -> 7 -> 8 -> 9 -> 1 -> 2 -> 3 -> 4 -> 5", linkedListToString(rotated)); } } diff --git a/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java b/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java index a47434083cdb..f80c6b5055f0 100644 --- a/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java +++ b/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java @@ -18,9 +18,9 @@ public class SinglyLinkedListTest { * @return linked list with pre-defined number of nodes */ private SinglyLinkedList createSampleList(int length) { - List nodeList = new ArrayList<>(); + List nodeList = new ArrayList<>(); for (int i = 1; i <= length; i++) { - Node node = new Node(i); + SinglyLinkedListNode node = new SinglyLinkedListNode(i); nodeList.add(node); } @@ -34,10 +34,10 @@ private SinglyLinkedList createSampleList(int length) { @Test void detectLoop() { // List has cycle - Node firstNode = new Node(1); - Node secondNode = new Node(2); - Node thirdNode = new Node(3); - Node fourthNode = new Node(4); + SinglyLinkedListNode firstNode = new SinglyLinkedListNode(1); + SinglyLinkedListNode secondNode = new SinglyLinkedListNode(2); + SinglyLinkedListNode thirdNode = new SinglyLinkedListNode(3); + SinglyLinkedListNode fourthNode = new SinglyLinkedListNode(4); firstNode.next = secondNode; secondNode.next = thirdNode; @@ -112,13 +112,13 @@ void reverseList() { // Reversing the LinkedList using reverseList() method and storing the head of the reversed // linkedlist in a head node The reversed linkedlist will be 4->3->2->1->null - Node head = list.reverseListIter(list.getHead()); + SinglyLinkedListNode head = list.reverseListIter(list.getHead()); // Recording the Nodes after reversing the LinkedList - Node firstNode = head; // 4 - Node secondNode = firstNode.next; // 3 - Node thirdNode = secondNode.next; // 2 - Node fourthNode = thirdNode.next; // 1 + SinglyLinkedListNode firstNode = head; // 4 + SinglyLinkedListNode secondNode = firstNode.next; // 3 + SinglyLinkedListNode thirdNode = secondNode.next; // 2 + SinglyLinkedListNode fourthNode = thirdNode.next; // 1 // Checking whether the LinkedList is reversed or not by comparing the original list and // reversed list nodes @@ -134,10 +134,10 @@ void reverseList() { void reverseListNullPointer() { // Creating a linkedlist with first node assigned to null SinglyLinkedList list = new SinglyLinkedList(); - Node first = list.getHead(); + SinglyLinkedListNode first = list.getHead(); // Reversing the linkedlist - Node head = list.reverseListIter(first); + SinglyLinkedListNode head = list.reverseListIter(first); // checking whether the method works fine if the input is null assertEquals(head, first); @@ -151,10 +151,10 @@ void reverseListTest() { // Reversing the LinkedList using reverseList() method and storing the head of the reversed // linkedlist in a head node - Node head = list.reverseListIter(list.getHead()); + SinglyLinkedListNode head = list.reverseListIter(list.getHead()); // Storing the head in a temp variable, so that we cannot loose the track of head - Node temp = head; + SinglyLinkedListNode temp = head; int i = 20; // This is for the comparison of values of nodes of the reversed linkedlist // Checking whether the reverseList() method performed its task @@ -171,7 +171,7 @@ void recursiveReverseList() { SinglyLinkedList list = createSampleList(5); // Reversing the linked list using reverseList() method - Node head = list.reverseListRec(list.getHead()); + SinglyLinkedListNode head = list.reverseListRec(list.getHead()); // Check if the reversed list is: 5 -> 4 -> 3 -> 2 -> 1 assertEquals(5, head.value); @@ -185,10 +185,10 @@ void recursiveReverseList() { void recursiveReverseListNullPointer() { // Create an empty linked list SinglyLinkedList list = new SinglyLinkedList(); - Node first = list.getHead(); + SinglyLinkedListNode first = list.getHead(); // Reversing the empty linked list - Node head = list.reverseListRec(first); + SinglyLinkedListNode head = list.reverseListRec(first); // Check if the head remains the same (null) assertNull(head); @@ -200,11 +200,11 @@ void recursiveReverseListTest() { SinglyLinkedList list = createSampleList(20); // Reversing the linked list using reverseList() method - Node head = list.reverseListRec(list.getHead()); + SinglyLinkedListNode head = list.reverseListRec(list.getHead()); // Check if the reversed list has the correct values int i = 20; - Node temp = head; + SinglyLinkedListNode temp = head; while (temp != null && i > 0) { assertEquals(i, temp.value); temp = temp.next; From 93e853575c98fa6c352097ffc21cb7baa5da3299 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 21:48:08 +0000 Subject: [PATCH 061/146] Bump org.jacoco:jacoco-maven-plugin from 0.8.12 to 0.8.13 (#6211) Bumps [org.jacoco:jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.12 to 0.8.13. - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.12...v0.8.13) --- updated-dependencies: - dependency-name: org.jacoco:jacoco-maven-plugin dependency-version: 0.8.13 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 42abb4d7c284..b98380c73f7b 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ org.jacoco jacoco-maven-plugin - 0.8.12 + 0.8.13 From c3d65e00cd9cf1a0e04aa86df8cba457496e1bbb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 21:52:04 +0000 Subject: [PATCH 062/146] Bump com.puppycrawl.tools:checkstyle from 10.22.0 to 10.23.0 (#6212) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.22.0 to 10.23.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.22.0...checkstyle-10.23.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 10.23.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b98380c73f7b..c644c7809884 100644 --- a/pom.xml +++ b/pom.xml @@ -115,7 +115,7 @@ com.puppycrawl.tools checkstyle - 10.22.0 + 10.23.0 From 2570a996648c2244b9b89196a4faf4710439c4ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Apr 2025 15:24:23 +0200 Subject: [PATCH 063/146] Bump org.mockito:mockito-core from 5.16.1 to 5.17.0 (#6213) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.16.1 to 5.17.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.16.1...v5.17.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-version: 5.17.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c644c7809884..3a38f08ad594 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ org.mockito mockito-core - 5.16.1 + 5.17.0 test From f53bc0080baf02209a176b12895f4f876502212d Mon Sep 17 00:00:00 2001 From: cureprotocols Date: Mon, 7 Apr 2025 14:58:44 -0600 Subject: [PATCH 064/146] Add ReservoirSampling algorithm to randomized module (#6204) --- .../randomized/ReservoirSampling.java | 55 +++++++++++++++++++ .../randomized/ReservoirSamplingTest.java | 45 +++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 src/main/java/com/thealgorithms/randomized/ReservoirSampling.java create mode 100644 src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java diff --git a/src/main/java/com/thealgorithms/randomized/ReservoirSampling.java b/src/main/java/com/thealgorithms/randomized/ReservoirSampling.java new file mode 100644 index 000000000000..05e70f635055 --- /dev/null +++ b/src/main/java/com/thealgorithms/randomized/ReservoirSampling.java @@ -0,0 +1,55 @@ +package com.thealgorithms.randomized; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Reservoir Sampling Algorithm + * + * Use Case: + * - Efficient for selecting k random items from a stream of unknown size + * - Used in streaming systems, big data, and memory-limited environments + * + * Time Complexity: O(n) + * Space Complexity: O(k) + * + * @author Michael Alexander Montoya (@cureprotocols) + * @see Reservoir Sampling - Wikipedia + */ +public final class ReservoirSampling { + + // Prevent instantiation of utility class + private ReservoirSampling() { + throw new UnsupportedOperationException("Utility class"); + } + + /** + * Selects k random elements from a stream using reservoir sampling. + * + * @param stream The input stream as an array of integers. + * @param sampleSize The number of elements to sample. + * @return A list containing k randomly selected elements. + */ + public static List sample(int[] stream, int sampleSize) { + if (sampleSize > stream.length) { + throw new IllegalArgumentException("Sample size cannot exceed stream size."); + } + + List reservoir = new ArrayList<>(sampleSize); + Random rand = new Random(); + + for (int i = 0; i < stream.length; i++) { + if (i < sampleSize) { + reservoir.add(stream[i]); + } else { + int j = rand.nextInt(i + 1); + if (j < sampleSize) { + reservoir.set(j, stream[i]); + } + } + } + + return reservoir; + } +} diff --git a/src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java b/src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java new file mode 100644 index 000000000000..0c6061fcde2a --- /dev/null +++ b/src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java @@ -0,0 +1,45 @@ +package com.thealgorithms.randomized; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class ReservoirSamplingTest { + + @Test + public void testSampleSizeEqualsStreamLength() { + int[] stream = {1, 2, 3, 4, 5}; + int sampleSize = 5; + + List result = ReservoirSampling.sample(stream, sampleSize); + + assertEquals(sampleSize, result.size()); + assertTrue(Arrays.stream(stream).allMatch(result::contains)); + } + + @Test + public void testSampleSizeLessThanStreamLength() { + int[] stream = {10, 20, 30, 40, 50, 60}; + int sampleSize = 3; + + List result = ReservoirSampling.sample(stream, sampleSize); + + assertEquals(sampleSize, result.size()); + for (int value : result) { + assertTrue(Arrays.stream(stream).anyMatch(x -> x == value)); + } + } + + @Test + public void testSampleSizeGreaterThanStreamLengthThrowsException() { + int[] stream = {1, 2, 3}; + + Exception exception = assertThrows(IllegalArgumentException.class, () -> ReservoirSampling.sample(stream, 5)); + + assertEquals("Sample size cannot exceed stream size.", exception.getMessage()); + } +} From ce6e734ddee4fb9c4298cb59a0f97f11ddc41af2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 12 Apr 2025 11:20:40 +0300 Subject: [PATCH 065/146] Bump org.junit:junit-bom from 5.12.1 to 5.12.2 (#6217) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3a38f08ad594..62851d2f55d2 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ org.junit junit-bom - 5.12.1 + 5.12.2 pom import From c8177e346f5cf3697d87ab435e370dcc7ef1f441 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 00:17:12 +0200 Subject: [PATCH 066/146] Bump DoozyX/clang-format-lint-action from 0.18 to 0.20 in /.github/workflows (#6223) Bump DoozyX/clang-format-lint-action in /.github/workflows Bumps [DoozyX/clang-format-lint-action](https://github.com/doozyx/clang-format-lint-action) from 0.18 to 0.20. - [Release notes](https://github.com/doozyx/clang-format-lint-action/releases) - [Commits](https://github.com/doozyx/clang-format-lint-action/compare/v0.18...v0.20) --- updated-dependencies: - dependency-name: DoozyX/clang-format-lint-action dependency-version: '0.20' dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/clang-format-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clang-format-lint.yml b/.github/workflows/clang-format-lint.yml index 588c05e42e8f..dac697511de1 100644 --- a/.github/workflows/clang-format-lint.yml +++ b/.github/workflows/clang-format-lint.yml @@ -9,7 +9,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: DoozyX/clang-format-lint-action@v0.18 + - uses: DoozyX/clang-format-lint-action@v0.20 with: source: './src' extensions: 'java' From ad5e496b0c105c6b4e16b8a9547473c51be85096 Mon Sep 17 00:00:00 2001 From: Vusal Huseynov <87518350+huseynovvusal@users.noreply.github.com> Date: Tue, 15 Apr 2025 17:08:45 +0400 Subject: [PATCH 067/146] Add LongestIncreasingSubsequenceNLogN (#6221) --- .../LongestIncreasingSubsequenceNLogN.java | 75 +++++++++++++++++++ ...LongestIncreasingSubsequenceNLogNTest.java | 22 ++++++ 2 files changed, 97 insertions(+) create mode 100644 src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogN.java create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogNTest.java diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogN.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogN.java new file mode 100644 index 000000000000..7bc0855e0566 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogN.java @@ -0,0 +1,75 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * Implementation of the Longest Increasing Subsequence (LIS) problem using + * an O(n log n) dynamic programming solution enhanced with binary search. + * + * @author Vusal Huseynov (https://github.com/huseynovvusal) + */ +public final class LongestIncreasingSubsequenceNLogN { + private LongestIncreasingSubsequenceNLogN() { + } + + /** + * Finds the index of the smallest element in the array that is greater than + * or equal to the target using binary search. The search is restricted to + * the first `size` elements of the array. + * + * @param arr The array to search in (assumed to be sorted up to `size`). + * @param size The number of valid elements in the array. + * @param target The target value to find the lower bound for. + * @return The index of the lower bound. + */ + private static int lowerBound(int[] arr, int target, int size) { + int l = 0; + int r = size; + + while (l < r) { + int mid = l + (r - l) / 2; + + if (target > arr[mid]) { + // Move right if target is greater than mid element + l = mid + 1; + } else { + // Move left if target is less than or equal to mid element + r = mid; + } + } + + // Return the index where the target can be inserted + return l; + } + + /** + * Calculates the length of the Longest Increasing Subsequence (LIS) in the given array. + * + * @param arr The input array of integers. + * @return The length of the LIS. + */ + public static int lengthOfLIS(int[] arr) { + if (arr == null || arr.length == 0) { + return 0; // Return 0 for empty or null arrays + } + + // tails[i] - the smallest end element of an increasing subsequence of length i+1 + int[] tails = new int[arr.length]; + // size - the length of the longest increasing subsequence found so far + int size = 0; + + for (int x : arr) { + // Find the position to replace or extend the subsequence + int index = lowerBound(tails, x, size); + + // Update the tails array with the current element + tails[index] = x; + + // If the element extends the subsequence, increase the size + if (index == size) { + size++; + } + } + + // Return the length of the LIS + return size; + } +} diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogNTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogNTest.java new file mode 100644 index 000000000000..dc87d6751460 --- /dev/null +++ b/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogNTest.java @@ -0,0 +1,22 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class LongestIncreasingSubsequenceNLogNTest { + + private static Stream provideTestCases() { + return Stream.of(Arguments.of(new int[] {10, 9, 2, 5, 3, 7, 101, 18}, 4), Arguments.of(new int[] {0, 1, 0, 3, 2, 3}, 4), Arguments.of(new int[] {7, 7, 7, 7, 7}, 1), Arguments.of(new int[] {1, 3, 5, 4, 7}, 4), Arguments.of(new int[] {}, 0), Arguments.of(new int[] {10}, 1), + Arguments.of(new int[] {3, 10, 2, 1, 20}, 3), Arguments.of(new int[] {50, 3, 10, 7, 40, 80}, 4)); + } + + @ParameterizedTest + @MethodSource("provideTestCases") + public void testLengthOfLIS(int[] input, int expected) { + assertEquals(expected, LongestIncreasingSubsequenceNLogN.lengthOfLIS(input)); + } +} From f91cae7e03bdcdf2bdbb665bfdf7b60b6060c0e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 00:28:23 +0300 Subject: [PATCH 068/146] Bump com.h3xstream.findsecbugs:findsecbugs-plugin from 1.13.0 to 1.14.0 (#6225) Bumps [com.h3xstream.findsecbugs:findsecbugs-plugin](https://github.com/find-sec-bugs/find-sec-bugs) from 1.13.0 to 1.14.0. - [Release notes](https://github.com/find-sec-bugs/find-sec-bugs/releases) - [Changelog](https://github.com/find-sec-bugs/find-sec-bugs/blob/master/CHANGELOG.md) - [Commits](https://github.com/find-sec-bugs/find-sec-bugs/commits) --- updated-dependencies: - dependency-name: com.h3xstream.findsecbugs:findsecbugs-plugin dependency-version: 1.14.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 62851d2f55d2..2459d8e0c9df 100644 --- a/pom.xml +++ b/pom.xml @@ -135,7 +135,7 @@ com.h3xstream.findsecbugs findsecbugs-plugin - 1.13.0 + 1.14.0 From 7a16daf9a74a8c24d29033d8485fa005fe751dd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 00:52:16 +0300 Subject: [PATCH 069/146] Bump org.apache.commons:commons-collections4 from 4.5.0-M3 to 4.5.0 (#6226) Bumps org.apache.commons:commons-collections4 from 4.5.0-M3 to 4.5.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-collections4 dependency-version: 4.5.0 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2459d8e0c9df..403c3d31728f 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ org.apache.commons commons-collections4 - 4.5.0-M3 + 4.5.0 From d866fbd32ad35a9e73444aa717cfcbf93a493437 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 10:27:51 +0300 Subject: [PATCH 070/146] Bump com.puppycrawl.tools:checkstyle from 10.23.0 to 10.23.1 (#6228) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.23.0 to 10.23.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.23.0...checkstyle-10.23.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 10.23.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 403c3d31728f..04128a7a3430 100644 --- a/pom.xml +++ b/pom.xml @@ -115,7 +115,7 @@ com.puppycrawl.tools checkstyle - 10.23.0 + 10.23.1 From 571d05caa8b851461d490cdfbba9124ee7af598a Mon Sep 17 00:00:00 2001 From: Muhammad Ezzat Date: Mon, 5 May 2025 18:09:28 +0300 Subject: [PATCH 071/146] Add Karger's minimum cut algorithm (#6233) --- .../randomized/KargerMinCut.java | 195 ++++++++++++++++++ .../randomized/KargerMinCutTest.java | 114 ++++++++++ 2 files changed, 309 insertions(+) create mode 100644 src/main/java/com/thealgorithms/randomized/KargerMinCut.java create mode 100644 src/test/java/com/thealgorithms/randomized/KargerMinCutTest.java diff --git a/src/main/java/com/thealgorithms/randomized/KargerMinCut.java b/src/main/java/com/thealgorithms/randomized/KargerMinCut.java new file mode 100644 index 000000000000..14f1f97450a0 --- /dev/null +++ b/src/main/java/com/thealgorithms/randomized/KargerMinCut.java @@ -0,0 +1,195 @@ +package com.thealgorithms.randomized; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; + +/** + * Implementation of Karger's Minimum Cut algorithm. + * + *

Karger's algorithm is a randomized algorithm to compute the minimum cut of a connected graph. + * A minimum cut is the smallest set of edges that, if removed, would split the graph into two + * disconnected components. + * + *

The algorithm works by repeatedly contracting random edges in the graph until only two + * nodes remain. The edges between these two nodes represent a cut. By running the algorithm + * multiple times and keeping track of the smallest cut found, the probability of finding the + * true minimum cut increases. + * + *

Key steps of the algorithm: + *

    + *
  1. Randomly select an edge and contract it, merging the two nodes into one.
  2. + *
  3. Repeat the contraction process until only two nodes remain.
  4. + *
  5. Count the edges between the two remaining nodes to determine the cut size.
  6. + *
  7. Repeat the process multiple times to improve the likelihood of finding the true minimum cut.
  8. + *
+ *

+ * See more: Karger's algorithm + * + * @author MuhammadEzzatHBK + */ +public final class KargerMinCut { + + /** + * Output of the Karger algorithm. + * + * @param first The first set of nodes in the cut. + * @param second The second set of nodes in the cut. + * @param minCut The size of the minimum cut. + */ + public record KargerOutput(Set first, Set second, int minCut) { + } + + private KargerMinCut() { + } + + public static KargerOutput findMinCut(Collection nodeSet, List edges) { + return findMinCut(nodeSet, edges, 100); + } + + /** + * Finds the minimum cut of a graph using Karger's algorithm. + * + * @param nodeSet: Input graph nodes + * @param edges: Input graph edges + * @param iterations: Iterations to run the algorithms for, more iterations = more accuracy + * @return A KargerOutput object containing the two sets of nodes and the size of the minimum cut. + */ + public static KargerOutput findMinCut(Collection nodeSet, List edges, int iterations) { + Graph graph = new Graph(nodeSet, edges); + KargerOutput minCut = new KargerOutput(new HashSet<>(), new HashSet<>(), Integer.MAX_VALUE); + KargerOutput output; + + // Run the algorithm multiple times to increase the probability of finding + for (int i = 0; i < iterations; i++) { + Graph clone = graph.copy(); + output = clone.findMinCut(); + if (output.minCut < minCut.minCut) { + minCut = output; + } + } + return minCut; + } + + private static class DisjointSetUnion { + private final int[] parent; + int setCount; + + DisjointSetUnion(int size) { + parent = new int[size]; + for (int i = 0; i < size; i++) { + parent[i] = i; + } + setCount = size; + } + + int find(int i) { + // If it's not its own parent, then it's not the root of its set + if (parent[i] != i) { + // Recursively find the root of its parent + // and update i's parent to point directly to the root (path compression) + parent[i] = find(parent[i]); + } + + // Return the root (representative) of the set + return parent[i]; + } + + void union(int u, int v) { + // Find the root of each node + int rootU = find(u); + int rootV = find(v); + + // If they belong to different sets, merge them + if (rootU != rootV) { + // Make rootV point to rootU — merge the two sets + parent[rootV] = rootU; + + // Reduce the count of disjoint sets by 1 + setCount--; + } + } + + boolean inSameSet(int u, int v) { + return find(u) == find(v); + } + + /* + This is a verbosity method, it's not a part of the core algorithm, + But it helps us provide more useful output. + */ + Set getAnySet() { + int aRoot = find(0); // Get one of the two roots + + Set set = new HashSet<>(); + for (int i = 0; i < parent.length; i++) { + if (find(i) == aRoot) { + set.add(i); + } + } + + return set; + } + } + + private static class Graph { + private final List nodes; + private final List edges; + + Graph(Collection nodeSet, List edges) { + this.nodes = new ArrayList<>(nodeSet); + this.edges = new ArrayList<>(); + for (int[] e : edges) { + this.edges.add(new int[] {e[0], e[1]}); + } + } + + Graph copy() { + return new Graph(this.nodes, this.edges); + } + + KargerOutput findMinCut() { + DisjointSetUnion dsu = new DisjointSetUnion(nodes.size()); + List workingEdges = new ArrayList<>(edges); + + Random rand = new Random(); + + while (dsu.setCount > 2) { + int[] e = workingEdges.get(rand.nextInt(workingEdges.size())); + if (!dsu.inSameSet(e[0], e[1])) { + dsu.union(e[0], e[1]); + } + } + + int cutEdges = 0; + for (int[] e : edges) { + if (!dsu.inSameSet(e[0], e[1])) { + cutEdges++; + } + } + + return collectResult(dsu, cutEdges); + } + + /* + This is a verbosity method, it's not a part of the core algorithm, + But it helps us provide more useful output. + */ + private KargerOutput collectResult(DisjointSetUnion dsu, int cutEdges) { + Set firstIndices = dsu.getAnySet(); + Set firstSet = new HashSet<>(); + Set secondSet = new HashSet<>(); + for (int i = 0; i < nodes.size(); i++) { + if (firstIndices.contains(i)) { + firstSet.add(nodes.get(i)); + } else { + secondSet.add(nodes.get(i)); + } + } + return new KargerOutput(firstSet, secondSet, cutEdges); + } + } +} diff --git a/src/test/java/com/thealgorithms/randomized/KargerMinCutTest.java b/src/test/java/com/thealgorithms/randomized/KargerMinCutTest.java new file mode 100644 index 000000000000..876b6bf45eaf --- /dev/null +++ b/src/test/java/com/thealgorithms/randomized/KargerMinCutTest.java @@ -0,0 +1,114 @@ +package com.thealgorithms.randomized; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class KargerMinCutTest { + + @Test + public void testSimpleGraph() { + // Graph: 0 -- 1 + Collection nodes = Arrays.asList(0, 1); + List edges = List.of(new int[] {0, 1}); + + KargerMinCut.KargerOutput result = KargerMinCut.findMinCut(nodes, edges); + + assertEquals(1, result.minCut()); + assertTrue(result.first().contains(0) || result.first().contains(1)); + assertTrue(result.second().contains(0) || result.second().contains(1)); + } + + @Test + public void testTriangleGraph() { + // Graph: 0 -- 1 -- 2 -- 0 + Collection nodes = Arrays.asList(0, 1, 2); + List edges = List.of(new int[] {0, 1}, new int[] {1, 2}, new int[] {2, 0}); + + KargerMinCut.KargerOutput result = KargerMinCut.findMinCut(nodes, edges); + + assertEquals(2, result.minCut()); + } + + @Test + public void testSquareGraph() { + // Graph: 0 -- 1 + // | | + // 3 -- 2 + Collection nodes = Arrays.asList(0, 1, 2, 3); + List edges = List.of(new int[] {0, 1}, new int[] {1, 2}, new int[] {2, 3}, new int[] {3, 0}); + + KargerMinCut.KargerOutput result = KargerMinCut.findMinCut(nodes, edges); + + assertEquals(2, result.minCut()); + } + + @Test + public void testDisconnectedGraph() { + // Graph: 0 -- 1 2 -- 3 + Collection nodes = Arrays.asList(0, 1, 2, 3); + List edges = List.of(new int[] {0, 1}, new int[] {2, 3}); + + KargerMinCut.KargerOutput result = KargerMinCut.findMinCut(nodes, edges); + + assertEquals(0, result.minCut()); + } + + @Test + public void testCompleteGraph() { + // Complete Graph: 0 -- 1 -- 2 -- 3 (all nodes connected to each other) + Collection nodes = Arrays.asList(0, 1, 2, 3); + List edges = List.of(new int[] {0, 1}, new int[] {0, 2}, new int[] {0, 3}, new int[] {1, 2}, new int[] {1, 3}, new int[] {2, 3}); + + KargerMinCut.KargerOutput result = KargerMinCut.findMinCut(nodes, edges); + + assertEquals(3, result.minCut()); + } + + @Test + public void testSingleNodeGraph() { + // Graph: Single node with no edges + Collection nodes = List.of(0); + List edges = List.of(); + + KargerMinCut.KargerOutput result = KargerMinCut.findMinCut(nodes, edges); + + assertEquals(0, result.minCut()); + assertTrue(result.first().contains(0)); + assertTrue(result.second().isEmpty()); + } + + @Test + public void testTwoNodesNoEdge() { + // Graph: 0 1 (no edges) + Collection nodes = Arrays.asList(0, 1); + List edges = List.of(); + + KargerMinCut.KargerOutput result = KargerMinCut.findMinCut(nodes, edges); + + assertEquals(0, result.minCut()); + assertTrue(result.first().contains(0) || result.first().contains(1)); + assertTrue(result.second().contains(0) || result.second().contains(1)); + } + + @Test + public void testComplexGraph() { + // Nodes: 0, 1, 2, 3, 4, 5, 6, 7, 8 + // Edges: Fully connected graph with additional edges for complexity + Collection nodes = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8); + List edges = List.of(new int[] {0, 1}, new int[] {0, 2}, new int[] {0, 3}, new int[] {0, 4}, new int[] {0, 5}, new int[] {1, 2}, new int[] {1, 3}, new int[] {1, 4}, new int[] {1, 5}, new int[] {1, 6}, new int[] {2, 3}, new int[] {2, 4}, new int[] {2, 5}, new int[] {2, 6}, + new int[] {2, 7}, new int[] {3, 4}, new int[] {3, 5}, new int[] {3, 6}, new int[] {3, 7}, new int[] {3, 8}, new int[] {4, 5}, new int[] {4, 6}, new int[] {4, 7}, new int[] {4, 8}, new int[] {5, 6}, new int[] {5, 7}, new int[] {5, 8}, new int[] {6, 7}, new int[] {6, 8}, new int[] {7, 8}, + new int[] {0, 6}, new int[] {1, 7}, new int[] {2, 8}); + + KargerMinCut.KargerOutput result = KargerMinCut.findMinCut(nodes, edges); + + // The exact minimum cut value depends on the randomization, but it should be consistent + // for this graph structure. For a fully connected graph, the minimum cut is typically + // determined by the smallest number of edges connecting two partitions. + assertTrue(result.minCut() > 0); + } +} From c02074e191102fe169a70cd7c585e87a2a048511 Mon Sep 17 00:00:00 2001 From: Andrii Siriak Date: Fri, 9 May 2025 23:10:36 +0300 Subject: [PATCH 072/146] Update CODEOWNERS --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0a19890aed44..8a0b18a54c0b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @yanglbme @vil02 @BamaCharanChhandogi @alxkm @siriak +* @DenizAltunkapan @yanglbme @vil02 @BamaCharanChhandogi @alxkm @siriak From 6fe630cdf2be76fdac75418890e129e67da8cf2b Mon Sep 17 00:00:00 2001 From: Muhammad Ezzat Date: Fri, 9 May 2025 23:27:27 +0300 Subject: [PATCH 073/146] Add Monte Carlo's Integral Approximation (#6235) --- .../randomized/MonteCarloIntegration.java | 82 +++++++++++++++++ .../randomized/MonteCarloIntegrationTest.java | 91 +++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 src/main/java/com/thealgorithms/randomized/MonteCarloIntegration.java create mode 100644 src/test/java/com/thealgorithms/randomized/MonteCarloIntegrationTest.java diff --git a/src/main/java/com/thealgorithms/randomized/MonteCarloIntegration.java b/src/main/java/com/thealgorithms/randomized/MonteCarloIntegration.java new file mode 100644 index 000000000000..05d7abbbcd6c --- /dev/null +++ b/src/main/java/com/thealgorithms/randomized/MonteCarloIntegration.java @@ -0,0 +1,82 @@ +package com.thealgorithms.randomized; + +import java.util.Random; +import java.util.function.Function; + +/** + * A demonstration of the Monte Carlo integration algorithm in Java. + * + *

This class estimates the value of definite integrals using randomized sampling, + * also known as the Monte Carlo method. It is particularly effective for: + *

    + *
  • Functions that are difficult or impossible to integrate analytically
  • + *
  • High-dimensional integrals where traditional methods are inefficient
  • + *
  • Simulation and probabilistic analysis tasks
  • + *
+ * + *

The core idea is to sample random points uniformly from the integration domain, + * evaluate the function at those points, and compute the scaled average to estimate the integral. + * + *

For a one-dimensional integral over [a, b], the approximation is the function range (b-a), + * multiplied by the function average result for a random sample. + * See more: Monte Carlo Integration + * + * @author: MuhammadEzzatHBK + */ + +public final class MonteCarloIntegration { + + private MonteCarloIntegration() { + } + + /** + * Approximates the definite integral of a given function over a specified + * interval using the Monte Carlo method with a fixed random seed for + * reproducibility. + * + * @param fx the function to integrate + * @param a the lower bound of the interval + * @param b the upper bound of the interval + * @param n the number of random samples to use + * @param seed the seed for the random number generator + * @return the approximate value of the integral + */ + public static double approximate(Function fx, double a, double b, int n, long seed) { + return doApproximate(fx, a, b, n, new Random(seed)); + } + + /** + * Approximates the definite integral of a given function over a specified + * interval using the Monte Carlo method with a random seed based on the + * current system time for more randomness. + * + * @param fx the function to integrate + * @param a the lower bound of the interval + * @param b the upper bound of the interval + * @param n the number of random samples to use + * @return the approximate value of the integral + */ + public static double approximate(Function fx, double a, double b, int n) { + return doApproximate(fx, a, b, n, new Random(System.currentTimeMillis())); + } + + private static double doApproximate(Function fx, double a, double b, int n, Random generator) { + if (!validate(fx, a, b, n)) { + throw new IllegalArgumentException("Invalid input parameters"); + } + double totalArea = 0.0; + double interval = b - a; + for (int i = 0; i < n; i++) { + double x = a + generator.nextDouble() * interval; + totalArea += fx.apply(x); + } + return interval * totalArea / n; + } + + private static boolean validate(Function fx, double a, double b, int n) { + boolean isFunctionValid = fx != null; + boolean isIntervalValid = a < b; + boolean isSampleSizeValid = n > 0; + return isFunctionValid && isIntervalValid && isSampleSizeValid; + } +} diff --git a/src/test/java/com/thealgorithms/randomized/MonteCarloIntegrationTest.java b/src/test/java/com/thealgorithms/randomized/MonteCarloIntegrationTest.java new file mode 100644 index 000000000000..2a3a84b5ceea --- /dev/null +++ b/src/test/java/com/thealgorithms/randomized/MonteCarloIntegrationTest.java @@ -0,0 +1,91 @@ +package com.thealgorithms.randomized; + +import static com.thealgorithms.randomized.MonteCarloIntegration.approximate; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.function.Function; +import org.junit.jupiter.api.Test; + +class MonteCarloIntegrationTest { + + private static final double EPSILON = 0.03; // Allow 3% error margin + + @Test + void testConstantFunction() { + // Integral of f(x) = 2 from 0 to 1 is 2 + Function constant = x -> 2.0; + double result = approximate(constant, 0, 1, 10000); + assertEquals(2.0, result, EPSILON); + } + + @Test + void testLinearFunction() { + // Integral of f(x) = x from 0 to 1 is 0.5 + Function linear = Function.identity(); + double result = approximate(linear, 0, 1, 10000); + assertEquals(0.5, result, EPSILON); + } + + @Test + void testQuadraticFunction() { + // Integral of f(x) = x^2 from 0 to 1 is 1/3 + Function quadratic = x -> x * x; + double result = approximate(quadratic, 0, 1, 10000); + assertEquals(1.0 / 3.0, result, EPSILON); + } + + @Test + void testLargeSampleSize() { + // Integral of f(x) = x^2 from 0 to 1 is 1/3 + Function quadratic = x -> x * x; + double result = approximate(quadratic, 0, 1, 50000000); + assertEquals(1.0 / 3.0, result, EPSILON / 2); // Larger sample size, smaller error margin + } + + @Test + void testReproducibility() { + Function linear = Function.identity(); + double result1 = approximate(linear, 0, 1, 10000, 42L); + double result2 = approximate(linear, 0, 1, 10000, 42L); + assertEquals(result1, result2, 0.0); // Exactly equal + } + + @Test + void testNegativeInterval() { + // Integral of f(x) = x from -1 to 1 is 0 + Function linear = Function.identity(); + double result = approximate(linear, -1, 1, 10000); + assertEquals(0.0, result, EPSILON); + } + + @Test + void testNullFunction() { + Exception exception = assertThrows(IllegalArgumentException.class, () -> approximate(null, 0, 1, 1000)); + assertNotNull(exception); + } + + @Test + void testInvalidInterval() { + Function linear = Function.identity(); + Exception exception = assertThrows(IllegalArgumentException.class, () -> { + approximate(linear, 2, 1, 1000); // b <= a + }); + assertNotNull(exception); + } + + @Test + void testZeroSampleSize() { + Function linear = Function.identity(); + Exception exception = assertThrows(IllegalArgumentException.class, () -> approximate(linear, 0, 1, 0)); + assertNotNull(exception); + } + + @Test + void testNegativeSampleSize() { + Function linear = Function.identity(); + Exception exception = assertThrows(IllegalArgumentException.class, () -> approximate(linear, 0, 1, -100)); + assertNotNull(exception); + } +} From b09766ede4474ca4e1148d46ce2d2705cb2c3ef0 Mon Sep 17 00:00:00 2001 From: Vibhu Khera Date: Sat, 10 May 2025 03:20:09 +0530 Subject: [PATCH 074/146] Add Randomized Quick Sort (#6234) --- .../randomized/RandomizedQuickSort.java | 68 +++++++++++++++++++ .../randomized/RandomizedQuickSortTest.java | 44 ++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 src/main/java/com/thealgorithms/randomized/RandomizedQuickSort.java create mode 100644 src/test/java/com/thealgorithms/randomized/RandomizedQuickSortTest.java diff --git a/src/main/java/com/thealgorithms/randomized/RandomizedQuickSort.java b/src/main/java/com/thealgorithms/randomized/RandomizedQuickSort.java new file mode 100644 index 000000000000..e9af223a0622 --- /dev/null +++ b/src/main/java/com/thealgorithms/randomized/RandomizedQuickSort.java @@ -0,0 +1,68 @@ +package com.thealgorithms.randomized; + +/** + * This class implements the Randomized QuickSort algorithm. + * It selects a pivot randomly to improve performance on sorted or nearly sorted data. + * @author Vibhu Khera + */ +public final class RandomizedQuickSort { + + private RandomizedQuickSort() { + throw new UnsupportedOperationException("Utility class"); + } + + /** + * Sorts the array using the randomized quicksort algorithm. + * + * @param arr the array to sort + * @param low the starting index of the array + * @param high the ending index of the array + */ + public static void randomizedQuickSort(int[] arr, int low, int high) { + if (low < high) { + int pivotIndex = partition(arr, low, high); + randomizedQuickSort(arr, low, pivotIndex - 1); + randomizedQuickSort(arr, pivotIndex + 1, high); + } + } + + /** + * Partitions the array around a pivot chosen randomly. + * + * @param arr the array to partition + * @param low the starting index + * @param high the ending index + * @return the index of the pivot after partitioning + */ + private static int partition(int[] arr, int low, int high) { + int pivotIndex = low + (int) (Math.random() * (high - low + 1)); + int pivotValue = arr[pivotIndex]; + swap(arr, pivotIndex, high); // Move pivot to end + int storeIndex = low; + for (int i = low; i < high; i++) { + if (arr[i] < pivotValue) { + swap(arr, storeIndex, i); + storeIndex++; + } + } + swap(arr, storeIndex, high); // Move pivot to its final place + return storeIndex; + } + + /** + * Swaps two elements in the array, only if the indices are different. + * + * @param arr the array in which elements are to be swapped + * @param i the first index + * @param j the second index + */ + private static void swap(int[] arr, int i, int j) { + // Skip if indices are the same + if (i == j) { + return; + } + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } +} diff --git a/src/test/java/com/thealgorithms/randomized/RandomizedQuickSortTest.java b/src/test/java/com/thealgorithms/randomized/RandomizedQuickSortTest.java new file mode 100644 index 000000000000..ec3d5a0b3546 --- /dev/null +++ b/src/test/java/com/thealgorithms/randomized/RandomizedQuickSortTest.java @@ -0,0 +1,44 @@ +package com.thealgorithms.randomized; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +/** + * Unit tests for the RandomizedQuickSort class. + */ +public class RandomizedQuickSortTest { + + /** + * Tests sorting of an array with multiple elements, including duplicates. + */ + @Test + public void testRandomizedQuickSortMultipleElements() { + int[] arr = {3, 6, 8, 10, 1, 2, 1}; + int[] expected = {1, 1, 2, 3, 6, 8, 10}; + RandomizedQuickSort.randomizedQuickSort(arr, 0, arr.length - 1); + assertArrayEquals(expected, arr); + } + + /** + * Tests sorting of an empty array. + */ + @Test + public void testRandomizedQuickSortEmptyArray() { + int[] arr = {}; + int[] expected = {}; + RandomizedQuickSort.randomizedQuickSort(arr, 0, arr.length - 1); + assertArrayEquals(expected, arr); + } + + /** + * Tests sorting of an array with a single element. + */ + @Test + public void testRandomizedQuickSortSingleElement() { + int[] arr = {5}; + int[] expected = {5}; + RandomizedQuickSort.randomizedQuickSort(arr, 0, arr.length - 1); + assertArrayEquals(expected, arr); + } +} From 121bf1eaf8e1e0f4c5b83d12ecc9f40f0a4d6eea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 May 2025 00:13:12 +0200 Subject: [PATCH 075/146] Bump org.mockito:mockito-core from 5.17.0 to 5.18.0 (#6240) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.17.0 to 5.18.0. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.17.0...v5.18.0) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-version: 5.18.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 04128a7a3430..2420f62fb97c 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ org.mockito mockito-core - 5.17.0 + 5.18.0 test From d23a0ec5f4d08cd8646606dfba1902bc79554b83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 May 2025 00:57:38 +0300 Subject: [PATCH 076/146] Bump com.puppycrawl.tools:checkstyle from 10.23.1 to 10.24.0 (#6246) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.23.1 to 10.24.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.23.1...checkstyle-10.24.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 10.24.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2420f62fb97c..415a0ae0cfd5 100644 --- a/pom.xml +++ b/pom.xml @@ -115,7 +115,7 @@ com.puppycrawl.tools checkstyle - 10.23.1 + 10.24.0 From 2320b46b3f2eb1a0088188936500c8de9cf60bf0 Mon Sep 17 00:00:00 2001 From: Soham Kamble <121136639+skamble2@users.noreply.github.com> Date: Wed, 28 May 2025 07:00:41 -0500 Subject: [PATCH 077/146] Add BTree implementation (#6248) --- .../datastructures/trees/BTree.java | 323 ++++++++++++++++++ .../datastructures/trees/BTreeTest.java | 94 +++++ 2 files changed, 417 insertions(+) create mode 100644 src/main/java/com/thealgorithms/datastructures/trees/BTree.java create mode 100644 src/test/java/com/thealgorithms/datastructures/trees/BTreeTest.java diff --git a/src/main/java/com/thealgorithms/datastructures/trees/BTree.java b/src/main/java/com/thealgorithms/datastructures/trees/BTree.java new file mode 100644 index 000000000000..2c19253b45e7 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/BTree.java @@ -0,0 +1,323 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.ArrayList; + +/** + * Implementation of a B-Tree, a self-balancing tree data structure that maintains sorted data + * and allows searches, sequential access, insertions, and deletions in logarithmic time. + * + * B-Trees are generalizations of binary search trees in that a node can have more than two children. + * They're widely used in databases and file systems. + * + * For more information: https://en.wikipedia.org/wiki/B-tree + */ + +public class BTree { + static class BTreeNode { + int[] keys; + int t; // Minimum degree (defines range for number of keys) + BTreeNode[] children; + int n; // Current number of keys + boolean leaf; + + BTreeNode(int t, boolean leaf) { + this.t = t; + this.leaf = leaf; + this.keys = new int[2 * t - 1]; + this.children = new BTreeNode[2 * t]; + this.n = 0; + } + + void traverse(ArrayList result) { + for (int i = 0; i < n; i++) { + if (!leaf) { + children[i].traverse(result); + } + result.add(keys[i]); + } + if (!leaf) { + children[n].traverse(result); + } + } + + BTreeNode search(int key) { + int i = 0; + while (i < n && key > keys[i]) { + i++; + } + if (i < n && keys[i] == key) { + return this; + } + if (leaf) { + return null; + } + return children[i].search(key); + } + + void insertNonFull(int key) { + int i = n - 1; + if (leaf) { + while (i >= 0 && keys[i] > key) { + keys[i + 1] = keys[i]; + i--; + } + keys[i + 1] = key; + n++; + } else { + while (i >= 0 && keys[i] > key) { + i--; + } + if (children[i + 1].n == 2 * t - 1) { + splitChild(i + 1, children[i + 1]); + if (keys[i + 1] < key) { + i++; + } + } + children[i + 1].insertNonFull(key); + } + } + + void splitChild(int i, BTreeNode y) { + BTreeNode z = new BTreeNode(y.t, y.leaf); + z.n = t - 1; + + System.arraycopy(y.keys, t, z.keys, 0, t - 1); + if (!y.leaf) { + System.arraycopy(y.children, t, z.children, 0, t); + } + y.n = t - 1; + + for (int j = n; j >= i + 1; j--) { + children[j + 1] = children[j]; + } + children[i + 1] = z; + + for (int j = n - 1; j >= i; j--) { + keys[j + 1] = keys[j]; + } + keys[i] = y.keys[t - 1]; + n++; + } + + void remove(int key) { + int idx = findKey(key); + + if (idx < n && keys[idx] == key) { + if (leaf) { + removeFromLeaf(idx); + } else { + removeFromNonLeaf(idx); + } + } else { + if (leaf) { + return; // Key not found + } + + boolean flag = idx == n; + if (children[idx].n < t) { + fill(idx); + } + + if (flag && idx > n) { + children[idx - 1].remove(key); + } else { + children[idx].remove(key); + } + } + } + + private int findKey(int key) { + int idx = 0; + while (idx < n && keys[idx] < key) { + ++idx; + } + return idx; + } + + private void removeFromLeaf(int idx) { + for (int i = idx + 1; i < n; ++i) { + keys[i - 1] = keys[i]; + } + n--; + } + + private void removeFromNonLeaf(int idx) { + int key = keys[idx]; + if (children[idx].n >= t) { + int pred = getPredecessor(idx); + keys[idx] = pred; + children[idx].remove(pred); + } else if (children[idx + 1].n >= t) { + int succ = getSuccessor(idx); + keys[idx] = succ; + children[idx + 1].remove(succ); + } else { + merge(idx); + children[idx].remove(key); + } + } + + private int getPredecessor(int idx) { + BTreeNode cur = children[idx]; + while (!cur.leaf) { + cur = cur.children[cur.n]; + } + return cur.keys[cur.n - 1]; + } + + private int getSuccessor(int idx) { + BTreeNode cur = children[idx + 1]; + while (!cur.leaf) { + cur = cur.children[0]; + } + return cur.keys[0]; + } + + private void fill(int idx) { + if (idx != 0 && children[idx - 1].n >= t) { + borrowFromPrev(idx); + } else if (idx != n && children[idx + 1].n >= t) { + borrowFromNext(idx); + } else { + if (idx != n) { + merge(idx); + } else { + merge(idx - 1); + } + } + } + + private void borrowFromPrev(int idx) { + BTreeNode child = children[idx]; + BTreeNode sibling = children[idx - 1]; + + for (int i = child.n - 1; i >= 0; --i) { + child.keys[i + 1] = child.keys[i]; + } + + if (!child.leaf) { + for (int i = child.n; i >= 0; --i) { + child.children[i + 1] = child.children[i]; + } + } + + child.keys[0] = keys[idx - 1]; + + if (!child.leaf) { + child.children[0] = sibling.children[sibling.n]; + } + + keys[idx - 1] = sibling.keys[sibling.n - 1]; + + child.n += 1; + sibling.n -= 1; + } + + private void borrowFromNext(int idx) { + BTreeNode child = children[idx]; + BTreeNode sibling = children[idx + 1]; + + child.keys[child.n] = keys[idx]; + + if (!child.leaf) { + child.children[child.n + 1] = sibling.children[0]; + } + + keys[idx] = sibling.keys[0]; + + for (int i = 1; i < sibling.n; ++i) { + sibling.keys[i - 1] = sibling.keys[i]; + } + + if (!sibling.leaf) { + for (int i = 1; i <= sibling.n; ++i) { + sibling.children[i - 1] = sibling.children[i]; + } + } + + child.n += 1; + sibling.n -= 1; + } + + private void merge(int idx) { + BTreeNode child = children[idx]; + BTreeNode sibling = children[idx + 1]; + + child.keys[t - 1] = keys[idx]; + + for (int i = 0; i < sibling.n; ++i) { + child.keys[i + t] = sibling.keys[i]; + } + + if (!child.leaf) { + for (int i = 0; i <= sibling.n; ++i) { + child.children[i + t] = sibling.children[i]; + } + } + + for (int i = idx + 1; i < n; ++i) { + keys[i - 1] = keys[i]; + } + + for (int i = idx + 2; i <= n; ++i) { + children[i - 1] = children[i]; + } + + child.n += sibling.n + 1; + n--; + } + } + + private BTreeNode root; + private final int t; + + public BTree(int t) { + this.root = null; + this.t = t; + } + + public void traverse(ArrayList result) { + if (root != null) { + root.traverse(result); + } + } + + public boolean search(int key) { + return root != null && root.search(key) != null; + } + + public void insert(int key) { + if (search(key)) { + return; + } + if (root == null) { + root = new BTreeNode(t, true); + root.keys[0] = key; + root.n = 1; + } else { + if (root.n == 2 * t - 1) { + BTreeNode s = new BTreeNode(t, false); + s.children[0] = root; + s.splitChild(0, root); + int i = 0; + if (s.keys[0] < key) { + i++; + } + s.children[i].insertNonFull(key); + root = s; + } else { + root.insertNonFull(key); + } + } + } + + public void delete(int key) { + if (root == null) { + return; + } + root.remove(key); + if (root.n == 0) { + root = root.leaf ? null : root.children[0]; + } + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/trees/BTreeTest.java b/src/test/java/com/thealgorithms/datastructures/trees/BTreeTest.java new file mode 100644 index 000000000000..da29e117f25d --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/trees/BTreeTest.java @@ -0,0 +1,94 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +public class BTreeTest { + + @Test + public void testInsertSearchDelete() { + BTree bTree = new BTree(3); // Minimum degree t = 3 + + int[] values = {10, 20, 5, 6, 12, 30, 7, 17}; + for (int val : values) { + bTree.insert(val); + } + + for (int val : values) { + assertTrue(bTree.search(val), "Should find inserted value: " + val); + } + + ArrayList traversal = new ArrayList<>(); + bTree.traverse(traversal); + assertEquals(Arrays.asList(5, 6, 7, 10, 12, 17, 20, 30), traversal); + + bTree.delete(6); + assertFalse(bTree.search(6)); + traversal.clear(); + bTree.traverse(traversal); + assertEquals(Arrays.asList(5, 7, 10, 12, 17, 20, 30), traversal); + } + + @Test + public void testEmptyTreeSearch() { + BTree bTree = new BTree(3); + assertFalse(bTree.search(42), "Search in empty tree should return false."); + } + + @Test + public void testDuplicateInsertions() { + BTree bTree = new BTree(3); + bTree.insert(15); + bTree.insert(15); // Attempt duplicate + bTree.insert(15); // Another duplicate + + ArrayList traversal = new ArrayList<>(); + bTree.traverse(traversal); + + // Should contain only one 15 + long count = traversal.stream().filter(x -> x == 15).count(); + assertEquals(1, count, "Duplicate keys should not be inserted."); + } + + @Test + public void testDeleteNonExistentKey() { + BTree bTree = new BTree(3); + bTree.insert(10); + bTree.insert(20); + bTree.delete(99); // Doesn't exist + assertTrue(bTree.search(10)); + assertTrue(bTree.search(20)); + } + + @Test + public void testComplexInsertDelete() { + BTree bTree = new BTree(2); // Smaller degree to trigger splits more easily + int[] values = {1, 3, 7, 10, 11, 13, 14, 15, 18, 16, 19, 24, 25, 26, 21, 4, 5, 20, 22, 2, 17, 12, 6}; + + for (int val : values) { + bTree.insert(val); + } + + for (int val : values) { + assertTrue(bTree.search(val)); + } + + int[] toDelete = {6, 13, 7, 4, 2, 16}; + for (int val : toDelete) { + bTree.delete(val); + assertFalse(bTree.search(val)); + } + + ArrayList remaining = new ArrayList<>(); + bTree.traverse(remaining); + + for (int val : toDelete) { + assertFalse(remaining.contains(val)); + } + } +} From 8e6637b7cd7d49dbef62e0e9811f4ad91146635e Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Tue, 3 Jun 2025 17:25:13 +0200 Subject: [PATCH 078/146] fix: use last known working commit for infer to avoid build failure (#6257) --- .github/workflows/infer.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/infer.yml b/.github/workflows/infer.yml index a07c6f458083..ffadd13ff3bd 100644 --- a/.github/workflows/infer.yml +++ b/.github/workflows/infer.yml @@ -41,6 +41,7 @@ jobs: cd .. git clone https://github.com/facebook/infer.git cd infer + git checkout 01aaa268f9d38723ba69c139e10f9e2a04b40b1c ./build-infer.sh java cp -r infer ../Java From 3b9bdcc066847adcc2a736ba70c6f84337f9b4d1 Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Tue, 3 Jun 2025 17:43:15 +0200 Subject: [PATCH 079/146] style: do not use `ArgumentsProvider` as deprecated (#6253) --- .../com/thealgorithms/sorts/SpreadSortTest.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/thealgorithms/sorts/SpreadSortTest.java b/src/test/java/com/thealgorithms/sorts/SpreadSortTest.java index a4992a02abfa..896aee8ba4ab 100644 --- a/src/test/java/com/thealgorithms/sorts/SpreadSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/SpreadSortTest.java @@ -6,8 +6,7 @@ import org.junit.jupiter.api.function.Executable; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.ArgumentsProvider; -import org.junit.jupiter.params.provider.ArgumentsSource; +import org.junit.jupiter.params.provider.MethodSource; public class SpreadSortTest extends SortingAlgorithmTest { @@ -20,16 +19,13 @@ SortAlgorithm getSortAlgorithm() { return new SpreadSort(); } - static class ConstructorArgumentsProvider implements ArgumentsProvider { - @Override - public Stream provideArguments(org.junit.jupiter.api.extension.ExtensionContext context) { - return Stream.of(Arguments.of(0, 16, 2, IllegalArgumentException.class), Arguments.of(16, 0, 2, IllegalArgumentException.class), Arguments.of(16, 16, 0, IllegalArgumentException.class), Arguments.of(1001, 16, 2, IllegalArgumentException.class), - Arguments.of(16, 1001, 2, IllegalArgumentException.class), Arguments.of(16, 16, 101, IllegalArgumentException.class)); - } + private static Stream wrongConstructorInputs() { + return Stream.of(Arguments.of(0, 16, 2, IllegalArgumentException.class), Arguments.of(16, 0, 2, IllegalArgumentException.class), Arguments.of(16, 16, 0, IllegalArgumentException.class), Arguments.of(1001, 16, 2, IllegalArgumentException.class), + Arguments.of(16, 1001, 2, IllegalArgumentException.class), Arguments.of(16, 16, 101, IllegalArgumentException.class)); } @ParameterizedTest - @ArgumentsSource(ConstructorArgumentsProvider.class) + @MethodSource("wrongConstructorInputs") void testConstructor(int insertionSortThreshold, int initialBucketCapacity, int minBuckets, Class expectedException) { Executable executable = () -> new SpreadSort(insertionSortThreshold, initialBucketCapacity, minBuckets); assertThrows(expectedException, executable); From 292b4e506e9fcd61b1e8cd753c2194343831e095 Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Tue, 3 Jun 2025 17:47:50 +0200 Subject: [PATCH 080/146] style: resolve `IMC_IMMATURE_CLASS_COLLECTION_RETURN` (#6256) --- src/test/java/com/thealgorithms/sorts/FlashSortTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/thealgorithms/sorts/FlashSortTest.java b/src/test/java/com/thealgorithms/sorts/FlashSortTest.java index 6b1a74403a59..5b27975d3bea 100644 --- a/src/test/java/com/thealgorithms/sorts/FlashSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/FlashSortTest.java @@ -5,7 +5,6 @@ import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; @@ -47,7 +46,7 @@ public void testCustomConstructorInvalidRatio(double ratio) { } @TestFactory - public Collection dynamicTestsForSorting() { + public List dynamicTestsForSorting() { List dynamicTests = new ArrayList<>(); double[] ratios = {0.1, 0.2, 0.5, 0.9}; @@ -60,7 +59,7 @@ public Collection dynamicTestsForSorting() { return dynamicTests; } - private Collection createDynamicTestsForRatio(double ratio) { + private List createDynamicTestsForRatio(double ratio) { List dynamicTests = new ArrayList<>(); for (TestMethod testMethod : getTestMethodsFromSuperClass()) { dynamicTests.add(DynamicTest.dynamicTest("Ratio: " + ratio + " - Test: " + testMethod.name(), testMethod.executable())); From 424c4fb0ebdac36cb9f110d865dfa2faf34b481f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jun 2025 16:08:41 +0000 Subject: [PATCH 081/146] Bump org.junit:junit-bom from 5.12.2 to 5.13.0 (#6252) * Bump org.junit:junit-bom from 5.12.2 to 5.13.0 Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.12.2 to 5.13.0. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.12.2...r5.13.0) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-version: 5.13.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Update directory --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 415a0ae0cfd5..dd32dfd59bfd 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ org.junit junit-bom - 5.12.2 + 5.13.0 pom import From d546212974251500e949693c9ad21921dec90e51 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jun 2025 16:16:47 +0000 Subject: [PATCH 082/146] Bump com.mebigfatguy.fb-contrib:fb-contrib from 7.6.9 to 7.6.10 (#6254) Bumps [com.mebigfatguy.fb-contrib:fb-contrib](https://github.com/mebigfatguy/fb-contrib) from 7.6.9 to 7.6.10. - [Commits](https://github.com/mebigfatguy/fb-contrib/commits/v7.6.10) --- updated-dependencies: - dependency-name: com.mebigfatguy.fb-contrib:fb-contrib dependency-version: 7.6.10 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dd32dfd59bfd..c98ff04b185d 100644 --- a/pom.xml +++ b/pom.xml @@ -130,7 +130,7 @@ com.mebigfatguy.fb-contrib fb-contrib - 7.6.9 + 7.6.10 com.h3xstream.findsecbugs From 30f39abfc4dd24e9b21ec6dbd54472957ddd0b02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jun 2025 16:24:14 +0000 Subject: [PATCH 083/146] Bump com.puppycrawl.tools:checkstyle from 10.24.0 to 10.25.0 (#6255) Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.24.0 to 10.25.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.24.0...checkstyle-10.25.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 10.25.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c98ff04b185d..b4ca8562ff9d 100644 --- a/pom.xml +++ b/pom.xml @@ -115,7 +115,7 @@ com.puppycrawl.tools checkstyle - 10.24.0 + 10.25.0 From b3c2c7a2319659d57898f35c5d5ede458c4a5925 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jun 2025 18:34:01 +0200 Subject: [PATCH 084/146] Bump gitpod/workspace-java-21 from 2025-02-10-10-54-28 to 2025-05-14-07-50-25 (#6249) Bump gitpod/workspace-java-21 Bumps gitpod/workspace-java-21 from 2025-02-10-10-54-28 to 2025-05-14-07-50-25. --- updated-dependencies: - dependency-name: gitpod/workspace-java-21 dependency-version: 2025-05-14-07-50-25 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .gitpod.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile index ea6d32a5a377..69fee306e1e4 100644 --- a/.gitpod.dockerfile +++ b/.gitpod.dockerfile @@ -1,4 +1,4 @@ -FROM gitpod/workspace-java-21:2025-02-10-10-54-28 +FROM gitpod/workspace-java-21:2025-05-14-07-50-25 ENV LLVM_SCRIPT="tmp_llvm.sh" From e123ca12c7d2d36dd76d322b8e02099ad3fedb0b Mon Sep 17 00:00:00 2001 From: Raveendra Pujari <72726513+raveendra11@users.noreply.github.com> Date: Tue, 3 Jun 2025 17:09:46 -0500 Subject: [PATCH 085/146] tests: properly test `Isomorphic` (#6259) Fixes #6258 --------- Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com> --- .../thealgorithms/strings/IsomorphicTest.java | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/test/java/com/thealgorithms/strings/IsomorphicTest.java b/src/test/java/com/thealgorithms/strings/IsomorphicTest.java index 0dac47551868..4dd13fbc34ee 100644 --- a/src/test/java/com/thealgorithms/strings/IsomorphicTest.java +++ b/src/test/java/com/thealgorithms/strings/IsomorphicTest.java @@ -1,31 +1,23 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; public final class IsomorphicTest { - private IsomorphicTest() { - } - - @Test - public static void main(String[] args) { - String str1 = "abbbbaac"; - String str2 = "kffffkkd"; - - String str3 = "xyxyxy"; - String str4 = "bnbnbn"; - String str5 = "ghjknnmm"; - String str6 = "wertpopo"; - - String str7 = "aaammmnnn"; - String str8 = "ggghhhbbj"; + @ParameterizedTest + @MethodSource("inputs") + public void testCheckStrings(String str1, String str2, Boolean expected) { + assertEquals(expected, Isomorphic.checkStrings(str1, str2)); + assertEquals(expected, Isomorphic.checkStrings(str2, str1)); + } - assertTrue(Isomorphic.checkStrings(str1, str2)); - assertTrue(Isomorphic.checkStrings(str3, str4)); - assertFalse(Isomorphic.checkStrings(str5, str6)); - assertFalse(Isomorphic.checkStrings(str7, str8)); + private static Stream inputs() { + return Stream.of(Arguments.of("", "", Boolean.TRUE), Arguments.of("", "a", Boolean.FALSE), Arguments.of("aaa", "aa", Boolean.FALSE), Arguments.of("abbbbaac", "kffffkkd", Boolean.TRUE), Arguments.of("xyxyxy", "bnbnbn", Boolean.TRUE), Arguments.of("ghjknnmm", "wertpopo", Boolean.FALSE), + Arguments.of("aaammmnnn", "ggghhhbbj", Boolean.FALSE)); } } From 27a774020cc89e1351fa973a36ecf546a6d53bd3 Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Wed, 4 Jun 2025 22:37:38 +0200 Subject: [PATCH 086/146] style: include `SLS_SUSPICIOUS_LOOP_SEARCH` (#6260) --- spotbugs-exclude.xml | 3 --- .../com/thealgorithms/ciphers/AffineCipher.java | 13 +------------ 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml index 3b77ced1a13e..bcc053611de6 100644 --- a/spotbugs-exclude.xml +++ b/spotbugs-exclude.xml @@ -195,9 +195,6 @@ - - - diff --git a/src/main/java/com/thealgorithms/ciphers/AffineCipher.java b/src/main/java/com/thealgorithms/ciphers/AffineCipher.java index b82681372f2b..979f18532eaa 100644 --- a/src/main/java/com/thealgorithms/ciphers/AffineCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/AffineCipher.java @@ -68,6 +68,7 @@ static String decryptCipher(String cipher) { // then i will be the multiplicative inverse of a if (flag == 1) { aInv = i; + break; } } for (int i = 0; i < cipher.length(); i++) { @@ -83,16 +84,4 @@ static String decryptCipher(String cipher) { return msg.toString(); } - - // Driver code - public static void main(String[] args) { - String msg = "AFFINE CIPHER"; - - // Calling encryption function - String cipherText = encryptMessage(msg.toCharArray()); - System.out.println("Encrypted Message is : " + cipherText); - - // Calling Decryption function - System.out.println("Decrypted Message is: " + decryptCipher(cipherText)); - } } From ec6f09c3738fc420b3ac68d315c65281d7fb1b01 Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Thu, 5 Jun 2025 13:23:28 +0200 Subject: [PATCH 087/146] chore: suppress `rawtypes` in selected classes (#6261) --- pom.xml | 1 - .../thealgorithms/backtracking/AllPathsFromSourceToTarget.java | 1 + .../thealgorithms/datastructures/bloomfilter/BloomFilter.java | 1 + .../java/com/thealgorithms/datastructures/graphs/Kruskal.java | 1 + .../com/thealgorithms/datastructures/graphs/WelshPowell.java | 1 + .../datastructures/hashmap/hashing/GenericHashMapUsingArray.java | 1 + .../thealgorithms/datastructures/hashmap/hashing/HashMap.java | 1 + .../datastructures/hashmap/hashing/LinearProbingHashMap.java | 1 + .../com/thealgorithms/datastructures/lists/CircleLinkedList.java | 1 + .../com/thealgorithms/datastructures/lists/CursorLinkedList.java | 1 + .../java/com/thealgorithms/datastructures/lists/SkipList.java | 1 + .../dynamicprogramming/LongestArithmeticSubsequence.java | 1 + .../java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java | 1 + src/main/java/com/thealgorithms/searches/FibonacciSearch.java | 1 + src/main/java/com/thealgorithms/sorts/MergeSort.java | 1 + src/main/java/com/thealgorithms/sorts/SortAlgorithm.java | 1 + src/main/java/com/thealgorithms/sorts/SpreadSort.java | 1 + src/main/java/com/thealgorithms/sorts/TimSort.java | 1 + .../com/thealgorithms/datastructures/graphs/KruskalTest.java | 1 + src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java | 1 + 20 files changed, 19 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b4ca8562ff9d..577634a4ceaa 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,6 @@ -Xlint:all -Xlint:-auxiliaryclass - -Xlint:-rawtypes -Xlint:-unchecked -Werror diff --git a/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java b/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java index 6f93b704ffb2..223b70fed66f 100644 --- a/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java +++ b/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java @@ -9,6 +9,7 @@ * * @author Siddhant Swarup Mallick */ +@SuppressWarnings("rawtypes") public class AllPathsFromSourceToTarget { // No. of vertices in graph diff --git a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java index a2edd3db2d8e..d60b95110fc2 100644 --- a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java +++ b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java @@ -12,6 +12,7 @@ * * @param The type of elements to be stored in the Bloom filter. */ +@SuppressWarnings("rawtypes") public class BloomFilter { private final int numberOfHashFunctions; diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java b/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java index 25c4548daa7a..edf466a9b2ec 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java @@ -19,6 +19,7 @@ * *

Time Complexity: O(E log V), where E is the number of edges and V is the number of vertices.

*/ +@SuppressWarnings("rawtypes") public class Kruskal { /** diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java b/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java index 26ca97736fe9..ff7230a9f348 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java @@ -22,6 +22,7 @@ * For more information, see Graph Coloring. *

*/ +@SuppressWarnings("rawtypes") public final class WelshPowell { private static final int BLANK_COLOR = -1; // Constant representing an uncolored state diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java index 3637e323f097..62e68329b47b 100644 --- a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java @@ -23,6 +23,7 @@ * @param the type of keys maintained by this hash map * @param the type of mapped values */ +@SuppressWarnings("rawtypes") public class GenericHashMapUsingArray { private int size; // Total number of key-value pairs diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java index aed39c941430..1b0792b8a738 100644 --- a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java @@ -8,6 +8,7 @@ * @param the type of keys maintained by this map * @param the type of mapped values */ +@SuppressWarnings("rawtypes") public class HashMap { private final int hashSize; private final LinkedList[] buckets; diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java index 10d5dc7decae..761a5fe83d18 100644 --- a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java @@ -34,6 +34,7 @@ * @param the type of keys maintained by this map * @param the type of mapped values */ +@SuppressWarnings("rawtypes") public class LinearProbingHashMap, Value> extends Map { private int hsize; // size of the hash table private Key[] keys; // array to store keys diff --git a/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java index 422e8953625f..72a12cd58401 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java @@ -10,6 +10,7 @@ * * @param the type of elements held in this list */ +@SuppressWarnings("rawtypes") public class CircleLinkedList { /** diff --git a/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java index ff3d39115c3b..24caf9d70bfe 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java @@ -10,6 +10,7 @@ * * @param the type of elements in this list */ +@SuppressWarnings("rawtypes") public class CursorLinkedList { /** diff --git a/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java b/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java index 3309ab24917d..f297cb79494c 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java @@ -29,6 +29,7 @@ * @param type of elements * @see Wiki. Skip list */ +@SuppressWarnings("rawtypes") public class SkipList> { /** diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java index b5ac62b4674b..2368332c410f 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java @@ -2,6 +2,7 @@ import java.util.HashMap; +@SuppressWarnings("rawtypes") final class LongestArithmeticSubsequence { private LongestArithmeticSubsequence() { } diff --git a/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java b/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java index 51dc099ba32e..c81476eaec32 100644 --- a/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java +++ b/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java @@ -10,6 +10,7 @@ * See more: * https://www.geeksforgeeks.org/function-to-check-if-a-singly-linked-list-is-palindrome/ */ +@SuppressWarnings("rawtypes") public final class PalindromeSinglyLinkedList { private PalindromeSinglyLinkedList() { } diff --git a/src/main/java/com/thealgorithms/searches/FibonacciSearch.java b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java index 2124938bc258..d6f53f8d944a 100644 --- a/src/main/java/com/thealgorithms/searches/FibonacciSearch.java +++ b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java @@ -15,6 +15,7 @@ * Note: This algorithm requires that the input array be sorted. *

*/ +@SuppressWarnings("rawtypes") public class FibonacciSearch implements SearchAlgorithm { /** diff --git a/src/main/java/com/thealgorithms/sorts/MergeSort.java b/src/main/java/com/thealgorithms/sorts/MergeSort.java index 9949783ca21b..86a184f67b26 100644 --- a/src/main/java/com/thealgorithms/sorts/MergeSort.java +++ b/src/main/java/com/thealgorithms/sorts/MergeSort.java @@ -7,6 +7,7 @@ * * @see SortAlgorithm */ +@SuppressWarnings("rawtypes") class MergeSort implements SortAlgorithm { private Comparable[] aux; diff --git a/src/main/java/com/thealgorithms/sorts/SortAlgorithm.java b/src/main/java/com/thealgorithms/sorts/SortAlgorithm.java index 7a3ded37bf3f..72b046d12861 100644 --- a/src/main/java/com/thealgorithms/sorts/SortAlgorithm.java +++ b/src/main/java/com/thealgorithms/sorts/SortAlgorithm.java @@ -8,6 +8,7 @@ * * @author Podshivalov Nikita (https://github.com/nikitap492) */ +@SuppressWarnings("rawtypes") public interface SortAlgorithm { /** * Main method arrays sorting algorithms diff --git a/src/main/java/com/thealgorithms/sorts/SpreadSort.java b/src/main/java/com/thealgorithms/sorts/SpreadSort.java index f1fd24f4735d..1401f3d454a8 100644 --- a/src/main/java/com/thealgorithms/sorts/SpreadSort.java +++ b/src/main/java/com/thealgorithms/sorts/SpreadSort.java @@ -6,6 +6,7 @@ * It distributes elements into buckets and recursively sorts these buckets. * This implementation is generic and can sort any array of elements that extend Comparable. */ +@SuppressWarnings("rawtypes") public class SpreadSort implements SortAlgorithm { private static final int MAX_INSERTION_SORT_THRESHOLD = 1000; private static final int MAX_INITIAL_BUCKET_CAPACITY = 1000; diff --git a/src/main/java/com/thealgorithms/sorts/TimSort.java b/src/main/java/com/thealgorithms/sorts/TimSort.java index 2d5bca2ef6f3..c592a74d1c8f 100644 --- a/src/main/java/com/thealgorithms/sorts/TimSort.java +++ b/src/main/java/com/thealgorithms/sorts/TimSort.java @@ -7,6 +7,7 @@ *

* For more details @see TimSort Algorithm */ +@SuppressWarnings("rawtypes") class TimSort implements SortAlgorithm { private static final int SUB_ARRAY_SIZE = 32; private Comparable[] aux; diff --git a/src/test/java/com/thealgorithms/datastructures/graphs/KruskalTest.java b/src/test/java/com/thealgorithms/datastructures/graphs/KruskalTest.java index b18f161ef1a6..c30dd2df26c5 100644 --- a/src/test/java/com/thealgorithms/datastructures/graphs/KruskalTest.java +++ b/src/test/java/com/thealgorithms/datastructures/graphs/KruskalTest.java @@ -10,6 +10,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +@SuppressWarnings("rawtypes") public class KruskalTest { private Kruskal kruskal; diff --git a/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java b/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java index 799052b22d83..561309e22ac9 100644 --- a/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java +++ b/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java @@ -8,6 +8,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +@SuppressWarnings("rawtypes") public class NumberOfDigitsTest { @ParameterizedTest From 7602f1ef4cc3adbb7bff92348abf338bd88d4d72 Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Thu, 5 Jun 2025 18:13:46 +0200 Subject: [PATCH 088/146] chore: suppress `unchecked` in selected classes (#6262) --- pom.xml | 1 - .../thealgorithms/backtracking/AllPathsFromSourceToTarget.java | 2 +- .../thealgorithms/datastructures/buffers/CircularBuffer.java | 1 + .../java/com/thealgorithms/datastructures/graphs/Kruskal.java | 2 +- .../com/thealgorithms/datastructures/graphs/WelshPowell.java | 2 +- .../hashmap/hashing/GenericHashMapUsingArray.java | 2 +- .../thealgorithms/datastructures/lists/CursorLinkedList.java | 2 +- .../java/com/thealgorithms/datastructures/lists/SkipList.java | 2 +- .../thealgorithms/datastructures/queues/QueueByTwoStacks.java | 1 + .../dynamicprogramming/LongestArithmeticSubsequence.java | 2 +- src/main/java/com/thealgorithms/others/CRCAlgorithm.java | 1 + src/main/java/com/thealgorithms/searches/FibonacciSearch.java | 2 +- src/main/java/com/thealgorithms/sorts/TimSort.java | 2 +- .../com/thealgorithms/datastructures/graphs/KruskalTest.java | 2 +- src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java | 2 +- 15 files changed, 14 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 577634a4ceaa..ae449cdfac31 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,6 @@ -Xlint:all -Xlint:-auxiliaryclass - -Xlint:-unchecked -Werror diff --git a/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java b/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java index 223b70fed66f..c35a36d97a57 100644 --- a/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java +++ b/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java @@ -9,7 +9,7 @@ * * @author Siddhant Swarup Mallick */ -@SuppressWarnings("rawtypes") +@SuppressWarnings({"rawtypes", "unchecked"}) public class AllPathsFromSourceToTarget { // No. of vertices in graph diff --git a/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java b/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java index b709e16fd1f6..3b89c2119ae0 100644 --- a/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java +++ b/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java @@ -10,6 +10,7 @@ * * @param The type of elements stored in the circular buffer. */ +@SuppressWarnings("unchecked") public class CircularBuffer { private final Item[] buffer; private final CircularPointer putPointer; diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java b/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java index edf466a9b2ec..331d7196b61c 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java @@ -19,7 +19,7 @@ * *

Time Complexity: O(E log V), where E is the number of edges and V is the number of vertices.

*/ -@SuppressWarnings("rawtypes") +@SuppressWarnings({"rawtypes", "unchecked"}) public class Kruskal { /** diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java b/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java index ff7230a9f348..4bf21c7ed4c1 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java @@ -22,7 +22,7 @@ * For more information, see Graph Coloring. *

*/ -@SuppressWarnings("rawtypes") +@SuppressWarnings({"rawtypes", "unchecked"}) public final class WelshPowell { private static final int BLANK_COLOR = -1; // Constant representing an uncolored state diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java index 62e68329b47b..36d2cc8df160 100644 --- a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java @@ -23,7 +23,7 @@ * @param the type of keys maintained by this hash map * @param the type of mapped values */ -@SuppressWarnings("rawtypes") +@SuppressWarnings({"rawtypes", "unchecked"}) public class GenericHashMapUsingArray { private int size; // Total number of key-value pairs diff --git a/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java index 24caf9d70bfe..63bb29034df2 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java @@ -10,7 +10,7 @@ * * @param the type of elements in this list */ -@SuppressWarnings("rawtypes") +@SuppressWarnings({"rawtypes", "unchecked"}) public class CursorLinkedList { /** diff --git a/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java b/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java index f297cb79494c..0b4fcd91483c 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java @@ -29,7 +29,7 @@ * @param type of elements * @see Wiki. Skip list */ -@SuppressWarnings("rawtypes") +@SuppressWarnings({"rawtypes", "unchecked"}) public class SkipList> { /** diff --git a/src/main/java/com/thealgorithms/datastructures/queues/QueueByTwoStacks.java b/src/main/java/com/thealgorithms/datastructures/queues/QueueByTwoStacks.java index 11e5e9b83892..981b3b32e0b2 100644 --- a/src/main/java/com/thealgorithms/datastructures/queues/QueueByTwoStacks.java +++ b/src/main/java/com/thealgorithms/datastructures/queues/QueueByTwoStacks.java @@ -11,6 +11,7 @@ * * @param The type of elements held in this queue. */ +@SuppressWarnings("unchecked") public class QueueByTwoStacks { private final Stack enqueueStk; diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java index 2368332c410f..ba1def551192 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java @@ -2,7 +2,7 @@ import java.util.HashMap; -@SuppressWarnings("rawtypes") +@SuppressWarnings({"rawtypes", "unchecked"}) final class LongestArithmeticSubsequence { private LongestArithmeticSubsequence() { } diff --git a/src/main/java/com/thealgorithms/others/CRCAlgorithm.java b/src/main/java/com/thealgorithms/others/CRCAlgorithm.java index 284a290a5af8..00ddc86be820 100644 --- a/src/main/java/com/thealgorithms/others/CRCAlgorithm.java +++ b/src/main/java/com/thealgorithms/others/CRCAlgorithm.java @@ -7,6 +7,7 @@ /** * @author dimgrichr */ +@SuppressWarnings("unchecked") public class CRCAlgorithm { private int correctMess; diff --git a/src/main/java/com/thealgorithms/searches/FibonacciSearch.java b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java index d6f53f8d944a..78dac0f0a712 100644 --- a/src/main/java/com/thealgorithms/searches/FibonacciSearch.java +++ b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java @@ -15,7 +15,7 @@ * Note: This algorithm requires that the input array be sorted. *

*/ -@SuppressWarnings("rawtypes") +@SuppressWarnings({"rawtypes", "unchecked"}) public class FibonacciSearch implements SearchAlgorithm { /** diff --git a/src/main/java/com/thealgorithms/sorts/TimSort.java b/src/main/java/com/thealgorithms/sorts/TimSort.java index c592a74d1c8f..13cd7fed35c7 100644 --- a/src/main/java/com/thealgorithms/sorts/TimSort.java +++ b/src/main/java/com/thealgorithms/sorts/TimSort.java @@ -7,7 +7,7 @@ *

* For more details @see TimSort Algorithm */ -@SuppressWarnings("rawtypes") +@SuppressWarnings({"rawtypes", "unchecked"}) class TimSort implements SortAlgorithm { private static final int SUB_ARRAY_SIZE = 32; private Comparable[] aux; diff --git a/src/test/java/com/thealgorithms/datastructures/graphs/KruskalTest.java b/src/test/java/com/thealgorithms/datastructures/graphs/KruskalTest.java index c30dd2df26c5..7291cd6c319c 100644 --- a/src/test/java/com/thealgorithms/datastructures/graphs/KruskalTest.java +++ b/src/test/java/com/thealgorithms/datastructures/graphs/KruskalTest.java @@ -10,7 +10,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -@SuppressWarnings("rawtypes") +@SuppressWarnings({"rawtypes", "unchecked"}) public class KruskalTest { private Kruskal kruskal; diff --git a/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java b/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java index 561309e22ac9..153ab3347f1e 100644 --- a/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java +++ b/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java @@ -8,7 +8,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -@SuppressWarnings("rawtypes") +@SuppressWarnings({"rawtypes", "unchecked"}) public class NumberOfDigitsTest { @ParameterizedTest From ed4a724e33903e63f5ddd8e531774b40e59bf46a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 22:52:11 +0200 Subject: [PATCH 089/146] Bump org.junit:junit-bom from 5.13.0 to 5.13.1 (#6278) Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.13.0 to 5.13.1. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.13.0...r5.13.1) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-version: 5.13.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ae449cdfac31..47506868a02b 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ org.junit junit-bom - 5.13.0 + 5.13.1 pom import From e41c2b9456f1bb25756095a58e8096994dbee10b Mon Sep 17 00:00:00 2001 From: Saipriya Patnaik <143923417+Saipatnaik-23@users.noreply.github.com> Date: Wed, 11 Jun 2025 02:37:24 +0530 Subject: [PATCH 090/146] Add Unit Tests for Empty and Single-Node Graphs in TopologicalSort (#6263) --- .../thealgorithms/sorts/TopologicalSortTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java b/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java index de115b458fe7..d5588b2b968e 100644 --- a/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertIterableEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.thealgorithms.sorts.TopologicalSort.Graph; import java.util.LinkedList; @@ -59,4 +60,18 @@ public void failureTest() { + "Back edge: 6 -> 2"; assertEquals(exception.getMessage(), expected); } + @Test + void testEmptyGraph() { + Graph graph = new Graph(); + LinkedList sorted = TopologicalSort.sort(graph); + assertTrue(sorted.isEmpty()); + } + @Test + void testSingleNode() { + Graph graph = new Graph(); + graph.addEdge("A", ""); + LinkedList sorted = TopologicalSort.sort(graph); + assertEquals(1, sorted.size()); + assertEquals("A", sorted.getFirst()); + } } From 20f04929be3f1f8ffc884350463e053490462d17 Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Wed, 11 Jun 2025 15:52:58 +0200 Subject: [PATCH 091/146] chore: configure PMD to detect `main` methods (#6289) --- pmd-custom_ruleset.xml | 28 ++++++++++++++ pmd-exclude.properties | 86 ++++++++++++++++++++++++++++++++++-------- pom.xml | 4 ++ 3 files changed, 103 insertions(+), 15 deletions(-) create mode 100644 pmd-custom_ruleset.xml diff --git a/pmd-custom_ruleset.xml b/pmd-custom_ruleset.xml new file mode 100644 index 000000000000..19bb1c7968f0 --- /dev/null +++ b/pmd-custom_ruleset.xml @@ -0,0 +1,28 @@ + + + + Custom PMD checks for TheAlgorithms/Java + + + + Avoid using the main method. + + 3 + + + + + + + + + diff --git a/pmd-exclude.properties b/pmd-exclude.properties index 1848412c9d30..4c0ed625d884 100644 --- a/pmd-exclude.properties +++ b/pmd-exclude.properties @@ -1,64 +1,120 @@ +com.thealgorithms.ciphers.AES=UselessMainMethod +com.thealgorithms.ciphers.AESEncryption=UselessMainMethod com.thealgorithms.ciphers.AffineCipher=UselessParentheses com.thealgorithms.ciphers.DES=UselessParentheses +com.thealgorithms.ciphers.ProductCipher=UselessMainMethod com.thealgorithms.ciphers.RSA=UselessParentheses -com.thealgorithms.conversions.AnyBaseToAnyBase=UselessParentheses +com.thealgorithms.conversions.AnyBaseToAnyBase=UselessMainMethod,UselessParentheses com.thealgorithms.conversions.AnytoAny=UselessParentheses +com.thealgorithms.conversions.RgbHsvConversion=UselessMainMethod com.thealgorithms.datastructures.crdt.Pair=UnusedPrivateField com.thealgorithms.datastructures.graphs.AStar=UselessParentheses com.thealgorithms.datastructures.graphs.AdjacencyMatrixGraph=CollapsibleIfStatements,UnnecessaryFullyQualifiedName,UselessParentheses +com.thealgorithms.datastructures.graphs.BellmanFord=UselessMainMethod com.thealgorithms.datastructures.graphs.BipartiteGraphDFS=CollapsibleIfStatements +com.thealgorithms.datastructures.graphs.ConnectedComponent=UselessMainMethod +com.thealgorithms.datastructures.graphs.Cycles=UselessMainMethod +com.thealgorithms.datastructures.graphs.Graphs=UselessMainMethod +com.thealgorithms.datastructures.graphs.KahnsAlgorithm=UselessMainMethod +com.thealgorithms.datastructures.graphs.MatrixGraphs=UselessMainMethod com.thealgorithms.datastructures.hashmap.hashing.HashMapCuckooHashing=UselessParentheses +com.thealgorithms.datastructures.hashmap.hashing.MainCuckooHashing=UselessMainMethod com.thealgorithms.datastructures.heaps.FibonacciHeap=UselessParentheses com.thealgorithms.datastructures.heaps.HeapNode=UselessParentheses com.thealgorithms.datastructures.lists.DoublyLinkedList=UselessParentheses +com.thealgorithms.datastructures.lists.Link=UselessMainMethod +com.thealgorithms.datastructures.lists.RandomNode=UselessMainMethod com.thealgorithms.datastructures.lists.SearchSinglyLinkedListRecursion=UselessParentheses -com.thealgorithms.datastructures.lists.SinglyLinkedList=UnusedLocalVariable +com.thealgorithms.datastructures.lists.SinglyLinkedList=UnusedLocalVariable,UselessMainMethod +com.thealgorithms.datastructures.queues.Deque=UselessMainMethod com.thealgorithms.datastructures.queues.PriorityQueue=UselessParentheses +com.thealgorithms.datastructures.trees.BSTRecursiveGeneric=UselessMainMethod com.thealgorithms.datastructures.trees.CheckBinaryTreeIsValidBST=UselessParentheses +com.thealgorithms.datastructures.trees.LCA=UselessMainMethod +com.thealgorithms.datastructures.trees.NearestRightKey=UselessMainMethod +com.thealgorithms.datastructures.trees.PrintTopViewofTree=UselessMainMethod com.thealgorithms.datastructures.trees.SegmentTree=UselessParentheses com.thealgorithms.devutils.nodes.LargeTreeNode=UselessParentheses com.thealgorithms.devutils.nodes.SimpleNode=UselessParentheses com.thealgorithms.devutils.nodes.SimpleTreeNode=UselessParentheses com.thealgorithms.devutils.nodes.TreeNode=UselessParentheses -com.thealgorithms.divideandconquer.ClosestPair=UnnecessaryFullyQualifiedName,UselessParentheses +com.thealgorithms.divideandconquer.ClosestPair=UnnecessaryFullyQualifiedName,UselessMainMethod,UselessParentheses com.thealgorithms.divideandconquer.Point=UselessParentheses +com.thealgorithms.dynamicprogramming.CatalanNumber=UselessMainMethod +com.thealgorithms.dynamicprogramming.EggDropping=UselessMainMethod +com.thealgorithms.dynamicprogramming.LongestPalindromicSubsequence=UselessMainMethod com.thealgorithms.dynamicprogramming.WineProblem=UselessParentheses com.thealgorithms.maths.BinomialCoefficient=UselessParentheses com.thealgorithms.maths.Complex=UselessParentheses com.thealgorithms.maths.DistanceFormulaTest=UnnecessaryFullyQualifiedName +com.thealgorithms.maths.EulerMethod=UselessMainMethod +com.thealgorithms.maths.GCDRecursion=UselessMainMethod com.thealgorithms.maths.Gaussian=UselessParentheses com.thealgorithms.maths.GcdSolutionWrapper=UselessParentheses com.thealgorithms.maths.HeronsFormula=UselessParentheses +com.thealgorithms.maths.JugglerSequence=UselessMainMethod com.thealgorithms.maths.KaprekarNumbers=UselessParentheses -com.thealgorithms.maths.KeithNumber=UselessParentheses +com.thealgorithms.maths.KeithNumber=UselessMainMethod,UselessParentheses com.thealgorithms.maths.LeonardoNumber=UselessParentheses -com.thealgorithms.maths.LinearDiophantineEquationsSolver=UselessParentheses +com.thealgorithms.maths.LinearDiophantineEquationsSolver=UselessMainMethod,UselessParentheses +com.thealgorithms.maths.MagicSquare=UselessMainMethod +com.thealgorithms.maths.PiNilakantha=UselessMainMethod +com.thealgorithms.maths.Prime.PrimeCheck=UselessMainMethod +com.thealgorithms.maths.PythagoreanTriple=UselessMainMethod com.thealgorithms.maths.RomanNumeralUtil=UselessParentheses com.thealgorithms.maths.SecondMinMax=UselessParentheses com.thealgorithms.maths.SecondMinMaxTest=UnnecessaryFullyQualifiedName +com.thealgorithms.maths.SimpsonIntegration=UselessMainMethod com.thealgorithms.maths.StandardDeviation=UselessParentheses com.thealgorithms.maths.SumOfArithmeticSeries=UselessParentheses -com.thealgorithms.maths.TrinomialTriangle=UselessParentheses +com.thealgorithms.maths.TrinomialTriangle=UselessMainMethod,UselessParentheses +com.thealgorithms.maths.VectorCrossProduct=UselessMainMethod com.thealgorithms.maths.Volume=UselessParentheses +com.thealgorithms.matrix.RotateMatrixBy90Degrees=UselessMainMethod com.thealgorithms.misc.Sparsity=UselessParentheses -com.thealgorithms.others.CRC16=UselessParentheses -com.thealgorithms.others.Damm=UnnecessaryFullyQualifiedName -com.thealgorithms.others.Luhn=UnnecessaryFullyQualifiedName -com.thealgorithms.others.Mandelbrot=UselessParentheses -com.thealgorithms.others.MiniMaxAlgorithm=UselessParentheses -com.thealgorithms.others.PageRank=UselessParentheses -com.thealgorithms.others.PerlinNoise=UselessParentheses +com.thealgorithms.others.BankersAlgorithm=UselessMainMethod +com.thealgorithms.others.BrianKernighanAlgorithm=UselessMainMethod +com.thealgorithms.others.CRC16=UselessMainMethod,UselessParentheses +com.thealgorithms.others.CRC32=UselessMainMethod +com.thealgorithms.others.Damm=UnnecessaryFullyQualifiedName,UselessMainMethod +com.thealgorithms.others.Dijkstra=UselessMainMethod +com.thealgorithms.others.GaussLegendre=UselessMainMethod +com.thealgorithms.others.HappyNumbersSeq=UselessMainMethod +com.thealgorithms.others.Huffman=UselessMainMethod +com.thealgorithms.others.InsertDeleteInArray=UselessMainMethod +com.thealgorithms.others.KochSnowflake=UselessMainMethod +com.thealgorithms.others.Krishnamurthy=UselessMainMethod +com.thealgorithms.others.LinearCongruentialGenerator=UselessMainMethod +com.thealgorithms.others.Luhn=UnnecessaryFullyQualifiedName,UselessMainMethod +com.thealgorithms.others.Mandelbrot=UselessMainMethod,UselessParentheses +com.thealgorithms.others.MiniMaxAlgorithm=UselessMainMethod,UselessParentheses +com.thealgorithms.others.PageRank=UselessMainMethod,UselessParentheses +com.thealgorithms.others.PerlinNoise=UselessMainMethod,UselessParentheses com.thealgorithms.others.QueueUsingTwoStacks=UselessParentheses -com.thealgorithms.others.Trieac=UselessParentheses -com.thealgorithms.others.Verhoeff=UnnecessaryFullyQualifiedName +com.thealgorithms.others.Trieac=UselessMainMethod,UselessParentheses +com.thealgorithms.others.Verhoeff=UnnecessaryFullyQualifiedName,UselessMainMethod +com.thealgorithms.puzzlesandgames.Sudoku=UselessMainMethod +com.thealgorithms.searches.HowManyTimesRotated=UselessMainMethod com.thealgorithms.searches.InterpolationSearch=UselessParentheses com.thealgorithms.searches.KMPSearch=UselessParentheses com.thealgorithms.searches.RabinKarpAlgorithm=UselessParentheses +com.thealgorithms.searches.RecursiveBinarySearch=UselessMainMethod +com.thealgorithms.sorts.BogoSort=UselessMainMethod com.thealgorithms.sorts.CircleSort=EmptyControlStatement com.thealgorithms.sorts.DutchNationalFlagSort=UselessParentheses com.thealgorithms.sorts.MergeSortNoExtraSpace=UselessParentheses com.thealgorithms.sorts.RadixSort=UselessParentheses +com.thealgorithms.sorts.TreeSort=UselessMainMethod com.thealgorithms.sorts.WiggleSort=UselessParentheses +com.thealgorithms.stacks.LargestRectangle=UselessMainMethod +com.thealgorithms.stacks.MaximumMinimumWindow=UselessMainMethod com.thealgorithms.stacks.PostfixToInfix=UselessParentheses +com.thealgorithms.strings.Alphabetical=UselessMainMethod com.thealgorithms.strings.HorspoolSearch=UnnecessaryFullyQualifiedName,UselessParentheses +com.thealgorithms.strings.KMP=UselessMainMethod +com.thealgorithms.strings.Lower=UselessMainMethod com.thealgorithms.strings.Palindrome=UselessParentheses +com.thealgorithms.strings.Pangram=UselessMainMethod +com.thealgorithms.strings.RabinKarp=UselessMainMethod +com.thealgorithms.strings.Rotation=UselessMainMethod +com.thealgorithms.strings.Upper=UselessMainMethod diff --git a/pom.xml b/pom.xml index 47506868a02b..eaf71ca899cc 100644 --- a/pom.xml +++ b/pom.xml @@ -143,6 +143,10 @@ maven-pmd-plugin 3.26.0 + + /rulesets/java/maven-pmd-plugin-default.xml + file://${basedir}/pmd-custom_ruleset.xml + true true false From 0b21bb0a3851e16f2386074e72ea25a7736bc39f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20L=C3=B3pez=20N=C3=BA=C3=B1ez?= Date: Wed, 11 Jun 2025 17:37:42 +0200 Subject: [PATCH 092/146] Add Boyer-Moore string search algorithm with JUnit tests (#6274) --- .../thealgorithms/searches/BoyerMoore.java | 58 +++++++++++++++++++ .../searches/BoyerMooreTest.java | 55 ++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 src/main/java/com/thealgorithms/searches/BoyerMoore.java create mode 100644 src/test/java/com/thealgorithms/searches/BoyerMooreTest.java diff --git a/src/main/java/com/thealgorithms/searches/BoyerMoore.java b/src/main/java/com/thealgorithms/searches/BoyerMoore.java new file mode 100644 index 000000000000..6998021503cc --- /dev/null +++ b/src/main/java/com/thealgorithms/searches/BoyerMoore.java @@ -0,0 +1,58 @@ +package com.thealgorithms.searches; + +/** + * Boyer-Moore string search algorithm. + * Efficient algorithm for substring search. + * https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string-search_algorithm + */ +public class BoyerMoore { + + private final int radix; // Radix (number of possible characters) + private final int[] right; // Bad character rule table + private final String pattern; + + public BoyerMoore(String pat) { + this.pattern = pat; + this.radix = 256; + this.right = new int[radix]; + + for (int c = 0; c < radix; c++) { + right[c] = -1; + } + + for (int j = 0; j < pat.length(); j++) { + right[pat.charAt(j)] = j; + } + } + + public int search(String text) { + if (pattern.isEmpty()) { + return 0; + } + + int m = pattern.length(); + int n = text.length(); + + int skip; + for (int i = 0; i <= n - m; i += skip) { + skip = 0; + for (int j = m - 1; j >= 0; j--) { + char txtChar = text.charAt(i + j); + char patChar = pattern.charAt(j); + if (patChar != txtChar) { + skip = Math.max(1, j - right[txtChar]); + break; + } + } + if (skip == 0) { + return i; // Match found + } + } + + return -1; // No match + } + + public static int staticSearch(String text, String pattern) { + return new BoyerMoore(pattern).search(text); + } +} diff --git a/src/test/java/com/thealgorithms/searches/BoyerMooreTest.java b/src/test/java/com/thealgorithms/searches/BoyerMooreTest.java new file mode 100644 index 000000000000..9021eacbb8ee --- /dev/null +++ b/src/test/java/com/thealgorithms/searches/BoyerMooreTest.java @@ -0,0 +1,55 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class BoyerMooreTest { + + @Test + public void testPatternFound() { + BoyerMoore bm = new BoyerMoore("ABCDABD"); + String text = "ABC ABCDAB ABCDABCDABDE"; + int index = bm.search(text); + assertEquals(15, index); + } + + @Test + public void testPatternNotFound() { + BoyerMoore bm = new BoyerMoore("XYZ"); + String text = "ABC ABCDAB ABCDABCDABDE"; + int index = bm.search(text); + assertEquals(-1, index); + } + + @Test + public void testPatternAtBeginning() { + BoyerMoore bm = new BoyerMoore("ABC"); + String text = "ABCDEF"; + int index = bm.search(text); + assertEquals(0, index); + } + + @Test + public void testPatternAtEnd() { + BoyerMoore bm = new BoyerMoore("CDE"); + String text = "ABCDEFGCDE"; + int index = bm.search(text); + assertEquals(2, index); // Primera ocurrencia de "CDE" + } + + @Test + public void testEmptyPattern() { + BoyerMoore bm = new BoyerMoore(""); + String text = "Hello world"; + int index = bm.search(text); + assertEquals(0, index); + } + + @Test + public void testStaticSearchMethod() { + String text = "ABCDEFGCDE"; + int index = BoyerMoore.staticSearch(text, "CDE"); + assertEquals(2, index); // Primera ocurrencia de "CDE" + } +} From 1745d19f09f636657c45e1f341e9f8d10357a687 Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Wed, 11 Jun 2025 19:04:06 +0200 Subject: [PATCH 093/146] refactor: unified duplicate Anagram classes into a single implementation (#6290) --- .../dynamicprogramming/UniquePaths.java | 9 +- .../dynamicprogramming/WildcardMatching.java | 5 +- .../thealgorithms/maths/DudeneyNumber.java | 4 +- .../scheduling/RRScheduling.java | 5 +- .../com/thealgorithms/strings/Anagrams.java | 35 +++--- .../thealgorithms/strings/CheckAnagrams.java | 110 ------------------ .../thealgorithms/strings/AnagramsTest.java | 13 ++- ...rSameTest.java => CharactersSameTest.java} | 0 .../strings/CheckAnagramsTest.java | 69 ----------- 9 files changed, 38 insertions(+), 212 deletions(-) delete mode 100644 src/main/java/com/thealgorithms/strings/CheckAnagrams.java rename src/test/java/com/thealgorithms/strings/{CharacterSameTest.java => CharactersSameTest.java} (100%) delete mode 100644 src/test/java/com/thealgorithms/strings/CheckAnagramsTest.java diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java b/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java index 80b553f2744c..22ad8a7dd8e3 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java @@ -1,3 +1,7 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.Arrays; + /** * Author: Siddhant Swarup Mallick * Github: https://github.com/siddhant2002 @@ -12,11 +16,6 @@ * This program calculates the number of unique paths possible for a robot to reach the bottom-right corner * of an m x n grid using dynamic programming. */ - -package com.thealgorithms.dynamicprogramming; - -import java.util.Arrays; - public final class UniquePaths { private UniquePaths() { diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java b/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java index 8e8bf3cc6606..8658ea30af00 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java @@ -1,3 +1,5 @@ +package com.thealgorithms.dynamicprogramming; + /** * * Author: Janmesh Singh @@ -11,9 +13,6 @@ * Use DP to return True if the pattern matches the entire text and False otherwise * */ - -package com.thealgorithms.dynamicprogramming; - public final class WildcardMatching { private WildcardMatching() { } diff --git a/src/main/java/com/thealgorithms/maths/DudeneyNumber.java b/src/main/java/com/thealgorithms/maths/DudeneyNumber.java index acf1e55d49c8..37f28e188663 100644 --- a/src/main/java/com/thealgorithms/maths/DudeneyNumber.java +++ b/src/main/java/com/thealgorithms/maths/DudeneyNumber.java @@ -1,11 +1,11 @@ +package com.thealgorithms.maths; + /** * A number is said to be Dudeney if the sum of the digits, is the cube root of the entered number. * Example- Let the number be 512, its sum of digits is 5+1+2=8. The cube root of 512 is also 8. * Since, the sum of the digits is equal to the cube root of the entered number; * it is a Dudeney Number. */ -package com.thealgorithms.maths; - public final class DudeneyNumber { private DudeneyNumber() { } diff --git a/src/main/java/com/thealgorithms/scheduling/RRScheduling.java b/src/main/java/com/thealgorithms/scheduling/RRScheduling.java index 110c97416a42..05efe1d59141 100644 --- a/src/main/java/com/thealgorithms/scheduling/RRScheduling.java +++ b/src/main/java/com/thealgorithms/scheduling/RRScheduling.java @@ -1,7 +1,3 @@ -/** - * @author Md Asif Joardar - */ - package com.thealgorithms.scheduling; import com.thealgorithms.devutils.entities.ProcessDetails; @@ -11,6 +7,7 @@ import java.util.Queue; /** + * @author Md Asif Joardar * The Round-robin scheduling algorithm is a kind of preemptive First come, First Serve CPU * Scheduling algorithm. This can be understood here - * https://www.scaler.com/topics/round-robin-scheduling-in-os/ diff --git a/src/main/java/com/thealgorithms/strings/Anagrams.java b/src/main/java/com/thealgorithms/strings/Anagrams.java index 4b24979e2689..5b97af0758f2 100644 --- a/src/main/java/com/thealgorithms/strings/Anagrams.java +++ b/src/main/java/com/thealgorithms/strings/Anagrams.java @@ -23,7 +23,9 @@ private Anagrams() { * @param t the second string * @return true if the strings are anagrams, false otherwise */ - public static boolean approach1(String s, String t) { + public static boolean areAnagramsBySorting(String s, String t) { + s = s.toLowerCase().replaceAll("[^a-z]", ""); + t = t.toLowerCase().replaceAll("[^a-z]", ""); if (s.length() != t.length()) { return false; } @@ -43,17 +45,18 @@ public static boolean approach1(String s, String t) { * @param t the second string * @return true if the strings are anagrams, false otherwise */ - public static boolean approach2(String s, String t) { - if (s.length() != t.length()) { - return false; + public static boolean areAnagramsByCountingChars(String s, String t) { + s = s.toLowerCase().replaceAll("[^a-z]", ""); + t = t.toLowerCase().replaceAll("[^a-z]", ""); + int[] dict = new int[128]; + for (char ch : s.toCharArray()) { + dict[ch]++; } - int[] charCount = new int[26]; - for (int i = 0; i < s.length(); i++) { - charCount[s.charAt(i) - 'a']++; - charCount[t.charAt(i) - 'a']--; + for (char ch : t.toCharArray()) { + dict[ch]--; } - for (int count : charCount) { - if (count != 0) { + for (int e : dict) { + if (e != 0) { return false; } } @@ -70,7 +73,9 @@ public static boolean approach2(String s, String t) { * @param t the second string * @return true if the strings are anagrams, false otherwise */ - public static boolean approach3(String s, String t) { + public static boolean areAnagramsByCountingCharsSingleArray(String s, String t) { + s = s.toLowerCase().replaceAll("[^a-z]", ""); + t = t.toLowerCase().replaceAll("[^a-z]", ""); if (s.length() != t.length()) { return false; } @@ -96,7 +101,9 @@ public static boolean approach3(String s, String t) { * @param t the second string * @return true if the strings are anagrams, false otherwise */ - public static boolean approach4(String s, String t) { + public static boolean areAnagramsUsingHashMap(String s, String t) { + s = s.toLowerCase().replaceAll("[^a-z]", ""); + t = t.toLowerCase().replaceAll("[^a-z]", ""); if (s.length() != t.length()) { return false; } @@ -123,7 +130,9 @@ public static boolean approach4(String s, String t) { * @param t the second string * @return true if the strings are anagrams, false otherwise */ - public static boolean approach5(String s, String t) { + public static boolean areAnagramsBySingleFreqArray(String s, String t) { + s = s.toLowerCase().replaceAll("[^a-z]", ""); + t = t.toLowerCase().replaceAll("[^a-z]", ""); if (s.length() != t.length()) { return false; } diff --git a/src/main/java/com/thealgorithms/strings/CheckAnagrams.java b/src/main/java/com/thealgorithms/strings/CheckAnagrams.java deleted file mode 100644 index 7bf7cd9a7c66..000000000000 --- a/src/main/java/com/thealgorithms/strings/CheckAnagrams.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.thealgorithms.strings; - -import java.util.HashMap; -import java.util.Map; - -/** - * Two strings are anagrams if they are made of the same letters arranged - * differently (ignoring the case). - */ -public final class CheckAnagrams { - private CheckAnagrams() { - } - /** - * Check if two strings are anagrams or not - * - * @param s1 the first string - * @param s2 the second string - * @return {@code true} if two string are anagrams, otherwise {@code false} - */ - public static boolean isAnagrams(String s1, String s2) { - int l1 = s1.length(); - int l2 = s2.length(); - s1 = s1.toLowerCase(); - s2 = s2.toLowerCase(); - Map charAppearances = new HashMap<>(); - - for (int i = 0; i < l1; i++) { - char c = s1.charAt(i); - int numOfAppearances = charAppearances.getOrDefault(c, 0); - charAppearances.put(c, numOfAppearances + 1); - } - - for (int i = 0; i < l2; i++) { - char c = s2.charAt(i); - if (!charAppearances.containsKey(c)) { - return false; - } - charAppearances.put(c, charAppearances.get(c) - 1); - } - - for (int cnt : charAppearances.values()) { - if (cnt != 0) { - return false; - } - } - return true; - } - - /** - * If given strings contain Unicode symbols. - * The first 128 ASCII codes are identical to Unicode. - * This algorithm is case-sensitive. - * - * @param s1 the first string - * @param s2 the second string - * @return true if two string are anagrams, otherwise false - */ - public static boolean isAnagramsUnicode(String s1, String s2) { - int[] dict = new int[128]; - for (char ch : s1.toCharArray()) { - dict[ch]++; - } - for (char ch : s2.toCharArray()) { - dict[ch]--; - } - for (int e : dict) { - if (e != 0) { - return false; - } - } - return true; - } - - /** - * If given strings contain only lowercase English letters. - *

- * The main "trick": - * To map each character from the first string 's1' we need to subtract an integer value of 'a' character - * as 'dict' array starts with 'a' character. - * - * @param s1 the first string - * @param s2 the second string - * @return true if two string are anagrams, otherwise false - */ - public static boolean isAnagramsOptimised(String s1, String s2) { - // 26 - English alphabet length - int[] dict = new int[26]; - for (char ch : s1.toCharArray()) { - checkLetter(ch); - dict[ch - 'a']++; - } - for (char ch : s2.toCharArray()) { - checkLetter(ch); - dict[ch - 'a']--; - } - for (int e : dict) { - if (e != 0) { - return false; - } - } - return true; - } - - private static void checkLetter(char ch) { - int index = ch - 'a'; - if (index < 0 || index >= 26) { - throw new IllegalArgumentException("Strings must contain only lowercase English letters!"); - } - } -} diff --git a/src/test/java/com/thealgorithms/strings/AnagramsTest.java b/src/test/java/com/thealgorithms/strings/AnagramsTest.java index 88f6e0bb72ec..fa8ea72f2b8c 100644 --- a/src/test/java/com/thealgorithms/strings/AnagramsTest.java +++ b/src/test/java/com/thealgorithms/strings/AnagramsTest.java @@ -13,36 +13,37 @@ record AnagramTestCase(String input1, String input2, boolean expected) { private static Stream anagramTestData() { return Stream.of(new AnagramTestCase("late", "tale", true), new AnagramTestCase("late", "teal", true), new AnagramTestCase("listen", "silent", true), new AnagramTestCase("hello", "olelh", true), new AnagramTestCase("hello", "world", false), new AnagramTestCase("deal", "lead", true), - new AnagramTestCase("binary", "brainy", true), new AnagramTestCase("adobe", "abode", true), new AnagramTestCase("cat", "act", true), new AnagramTestCase("cat", "cut", false)); + new AnagramTestCase("binary", "brainy", true), new AnagramTestCase("adobe", "abode", true), new AnagramTestCase("cat", "act", true), new AnagramTestCase("cat", "cut", false), new AnagramTestCase("Listen", "Silent", true), new AnagramTestCase("Dormitory", "DirtyRoom", true), + new AnagramTestCase("Schoolmaster", "TheClassroom", true), new AnagramTestCase("Astronomer", "MoonStarer", true), new AnagramTestCase("Conversation", "VoicesRantOn", true)); } @ParameterizedTest @MethodSource("anagramTestData") void testApproach1(AnagramTestCase testCase) { - assertEquals(testCase.expected(), Anagrams.approach1(testCase.input1(), testCase.input2())); + assertEquals(testCase.expected(), Anagrams.areAnagramsBySorting(testCase.input1(), testCase.input2())); } @ParameterizedTest @MethodSource("anagramTestData") void testApproach2(AnagramTestCase testCase) { - assertEquals(testCase.expected(), Anagrams.approach2(testCase.input1(), testCase.input2())); + assertEquals(testCase.expected(), Anagrams.areAnagramsByCountingChars(testCase.input1(), testCase.input2())); } @ParameterizedTest @MethodSource("anagramTestData") void testApproach3(AnagramTestCase testCase) { - assertEquals(testCase.expected(), Anagrams.approach3(testCase.input1(), testCase.input2())); + assertEquals(testCase.expected(), Anagrams.areAnagramsByCountingCharsSingleArray(testCase.input1(), testCase.input2())); } @ParameterizedTest @MethodSource("anagramTestData") void testApproach4(AnagramTestCase testCase) { - assertEquals(testCase.expected(), Anagrams.approach4(testCase.input1(), testCase.input2())); + assertEquals(testCase.expected(), Anagrams.areAnagramsUsingHashMap(testCase.input1(), testCase.input2())); } @ParameterizedTest @MethodSource("anagramTestData") void testApproach5(AnagramTestCase testCase) { - assertEquals(testCase.expected(), Anagrams.approach5(testCase.input1(), testCase.input2())); + assertEquals(testCase.expected(), Anagrams.areAnagramsBySingleFreqArray(testCase.input1(), testCase.input2())); } } diff --git a/src/test/java/com/thealgorithms/strings/CharacterSameTest.java b/src/test/java/com/thealgorithms/strings/CharactersSameTest.java similarity index 100% rename from src/test/java/com/thealgorithms/strings/CharacterSameTest.java rename to src/test/java/com/thealgorithms/strings/CharactersSameTest.java diff --git a/src/test/java/com/thealgorithms/strings/CheckAnagramsTest.java b/src/test/java/com/thealgorithms/strings/CheckAnagramsTest.java deleted file mode 100644 index 82a75a130ef0..000000000000 --- a/src/test/java/com/thealgorithms/strings/CheckAnagramsTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.thealgorithms.strings; - -import static org.junit.jupiter.api.Assertions.assertThrows; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -public class CheckAnagramsTest { - private static final String MESSAGE = "Strings must contain only lowercase English letters!"; - - // CHECK METHOD isAnagrams() - @Test - public void testCheckAnagrams() { - String testString1 = "STUDY"; - String testString2 = "DUSTY"; - Assertions.assertTrue(CheckAnagrams.isAnagrams(testString1, testString2)); - } - - @Test - public void testCheckFalseAnagrams() { - String testString1 = "STUDY"; - String testString2 = "random"; - Assertions.assertFalse(CheckAnagrams.isAnagrams(testString1, testString2)); - } - - @Test - public void testCheckSameWordAnagrams() { - String testString1 = "STUDY"; - Assertions.assertTrue(CheckAnagrams.isAnagrams(testString1, testString1)); - } - - @Test - public void testCheckDifferentCasesAnagram() { - String testString1 = "STUDY"; - String testString2 = "dusty"; - Assertions.assertTrue(CheckAnagrams.isAnagrams(testString1, testString2)); - } - - // CHECK METHOD isAnagramsUnicode() - // Below tests work with strings which consist of Unicode symbols & the algorithm is case-sensitive. - @Test - public void testStringAreValidAnagramsCaseSensitive() { - Assertions.assertTrue(CheckAnagrams.isAnagramsUnicode("Silent", "liSten")); - Assertions.assertTrue(CheckAnagrams.isAnagramsUnicode("This is a string", "is This a string")); - } - - @Test - public void testStringAreNotAnagramsCaseSensitive() { - Assertions.assertFalse(CheckAnagrams.isAnagramsUnicode("Silent", "Listen")); - Assertions.assertFalse(CheckAnagrams.isAnagramsUnicode("This is a string", "Is this a string")); - } - - // CHECK METHOD isAnagramsOptimised() - // Below tests work with strings which consist of only lowercase English letters - @Test - public void testOptimisedAlgorithmStringsAreValidAnagrams() { - Assertions.assertTrue(CheckAnagrams.isAnagramsOptimised("silent", "listen")); - Assertions.assertTrue(CheckAnagrams.isAnagramsOptimised("mam", "amm")); - } - - @Test - public void testOptimisedAlgorithmShouldThrowExceptionWhenStringsContainUppercaseLetters() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CheckAnagrams.isAnagramsOptimised("Silent", "Listen")); - Assertions.assertEquals(exception.getMessage(), MESSAGE); - - exception = assertThrows(IllegalArgumentException.class, () -> Assertions.assertFalse(CheckAnagrams.isAnagramsOptimised("This is a string", "Is this a string"))); - Assertions.assertEquals(exception.getMessage(), MESSAGE); - } -} From b427b40f5637d30e36a41ade79fa42dea424604c Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Thu, 12 Jun 2025 17:35:01 +0200 Subject: [PATCH 094/146] chore: monitor structure of the project (#6291) --- .github/workflows/project_structure.yml | 22 ++++++++++++++++ .github/workflows/scripts/check_structure.py | 27 ++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 .github/workflows/project_structure.yml create mode 100644 .github/workflows/scripts/check_structure.py diff --git a/.github/workflows/project_structure.yml b/.github/workflows/project_structure.yml new file mode 100644 index 000000000000..def01554a4f8 --- /dev/null +++ b/.github/workflows/project_structure.yml @@ -0,0 +1,22 @@ +--- +name: ProjectStructure + +'on': + workflow_dispatch: + push: + branches: + - master + pull_request: + +jobs: + check_structure: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.13' + + - name: Check project structure + run: python3 .github/workflows/scripts/check_structure.py +... diff --git a/.github/workflows/scripts/check_structure.py b/.github/workflows/scripts/check_structure.py new file mode 100644 index 000000000000..914f64369207 --- /dev/null +++ b/.github/workflows/scripts/check_structure.py @@ -0,0 +1,27 @@ +import pathlib +import sys + + +def _is_java_file_properly_located(java_file: pathlib.Path) -> bool: + main_parents = java_file.parent.parents + return ( + pathlib.Path("src/main/java/com/thealgorithms/") in main_parents + or pathlib.Path("src/test/java/com/thealgorithms/") in main_parents + ) + + +def _find_misplaced_java_files() -> list[pathlib.Path]: + return [ + java_file + for java_file in pathlib.Path(".").rglob("*.java") + if not _is_java_file_properly_located(java_file) + ] + + +if __name__ == "__main__": + misplaced_files = _find_misplaced_java_files() + if misplaced_files: + print("The following java files are not located in the correct directory:") + for _ in misplaced_files: + print(_) + sys.exit(1) From a21abe6b2b6fe7a0d42804c9f5e09422c1954098 Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Sat, 14 Jun 2025 18:42:45 +0200 Subject: [PATCH 095/146] chore: add `security` ruleset to PMD (#6292) --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index eaf71ca899cc..a87a7157c2f9 100644 --- a/pom.xml +++ b/pom.xml @@ -145,6 +145,7 @@ /rulesets/java/maven-pmd-plugin-default.xml + /category/java/security.xml file://${basedir}/pmd-custom_ruleset.xml true From 616d15a40828d4b2399e637e6f2fe9e112677b9e Mon Sep 17 00:00:00 2001 From: 02RdDT <61636396+DomTr@users.noreply.github.com> Date: Wed, 18 Jun 2025 22:29:35 +0300 Subject: [PATCH 096/146] Shortest coprime segment using sliding window technique (#6296) * Shortest coprime segment using sliding window technique * mvn checkstyle passes * gcd function reformatted * fixed typo in ShortestCoprimeSegment * 1. shortestCoprimeSegment now returns not the length, but the shortest segment itself. 2. Testcases have been adapted, a few new ones added. * clang formatted ShortestCoprimeSegmentTest.java code --- .../slidingwindow/ShortestCoprimeSegment.java | 135 ++++++++++++++++++ .../ShortestCoprimeSegmentTest.java | 65 +++++++++ 2 files changed, 200 insertions(+) create mode 100644 src/main/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegment.java create mode 100644 src/test/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegmentTest.java diff --git a/src/main/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegment.java b/src/main/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegment.java new file mode 100644 index 000000000000..b99f7ca7d62f --- /dev/null +++ b/src/main/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegment.java @@ -0,0 +1,135 @@ +package com.thealgorithms.slidingwindow; + +import java.util.Arrays; +import java.util.LinkedList; + +/** + * The Sliding Window technique together with 2-stack technique is used to find coprime segment of minimal size in an array. + * Segment a[i],...,a[i+l] is coprime if gcd(a[i], a[i+1], ..., a[i+l]) = 1 + *

+ * Run-time complexity: O(n log n) + * What is special about this 2-stack technique is that it enables us to remove element a[i] and find gcd(a[i+1],...,a[i+l]) in amortized O(1) time. + * For 'remove' worst-case would be O(n) operation, but this happens rarely. + * Main observation is that each element gets processed a constant amount of times, hence complexity will be: + * O(n log n), where log n comes from complexity of gcd. + *

+ * More generally, the 2-stack technique enables us to 'remove' an element fast if it is known how to 'add' an element fast to the set. + * In our case 'adding' is calculating d' = gcd(a[i],...,a[i+l+1]), when d = gcd(a[i],...a[i]) with d' = gcd(d, a[i+l+1]). + * and removing is find gcd(a[i+1],...,a[i+l]). We don't calculate it explicitly, but it is pushed in the stack which we can pop in O(1). + *

+ * One can change methods 'legalSegment' and function 'f' in DoubleStack to adapt this code to other sliding-window type problems. + * I recommend this article for more explanations: "CF Article">Article 1 or USACO Article + *

+ * Another method to solve this problem is through segment trees. Then query operation would have O(log n), not O(1) time, but runtime complexity would still be O(n log n) + * + * @author DomTr (Github) + */ +public final class ShortestCoprimeSegment { + // Prevent instantiation + private ShortestCoprimeSegment() { + } + + /** + * @param arr is the input array + * @return shortest segment in the array which has gcd equal to 1. If no such segment exists or array is empty, returns empty array + */ + public static long[] shortestCoprimeSegment(long[] arr) { + if (arr == null || arr.length == 0) { + return new long[] {}; + } + DoubleStack front = new DoubleStack(); + DoubleStack back = new DoubleStack(); + int n = arr.length; + int l = 0; + int shortestLength = n + 1; + int beginsAt = -1; // beginning index of the shortest coprime segment + for (int i = 0; i < n; i++) { + back.push(arr[i]); + while (legalSegment(front, back)) { + remove(front, back); + if (shortestLength > i - l + 1) { + beginsAt = l; + shortestLength = i - l + 1; + } + l++; + } + } + if (shortestLength > n) { + shortestLength = -1; + } + if (shortestLength == -1) { + return new long[] {}; + } + return Arrays.copyOfRange(arr, beginsAt, beginsAt + shortestLength); + } + + private static boolean legalSegment(DoubleStack front, DoubleStack back) { + return gcd(front.top(), back.top()) == 1; + } + + private static long gcd(long a, long b) { + if (a < b) { + return gcd(b, a); + } else if (b == 0) { + return a; + } else { + return gcd(a % b, b); + } + } + + /** + * This solves the problem of removing elements quickly. + * Even though the worst case of 'remove' method is O(n), it is a very pessimistic view. + * We will need to empty out 'back', only when 'from' is empty. + * Consider element x when it is added to stack 'back'. + * After some time 'front' becomes empty and x goes to 'front'. Notice that in the for-loop we proceed further and x will never come back to any stacks 'back' or 'front'. + * In other words, every element gets processed by a constant number of operations. + * So 'remove' amortized runtime is actually O(n). + */ + private static void remove(DoubleStack front, DoubleStack back) { + if (front.isEmpty()) { + while (!back.isEmpty()) { + front.push(back.pop()); + } + } + front.pop(); + } + + /** + * DoubleStack serves as a collection of two stacks. One is a normal stack called 'stack', the other 'values' stores gcd-s up until some index. + */ + private static class DoubleStack { + LinkedList stack; + LinkedList values; + + DoubleStack() { + values = new LinkedList<>(); + stack = new LinkedList<>(); + values.add(0L); // Initialise with 0 which is neutral element in terms of gcd, i.e. gcd(a,0) = a + } + + long f(long a, long b) { // Can be replaced with other function + return gcd(a, b); + } + + public void push(long x) { + stack.addLast(x); + values.addLast(f(values.getLast(), x)); + } + + public long top() { + return values.getLast(); + } + + public long pop() { + long res = stack.getLast(); + stack.removeLast(); + values.removeLast(); + return res; + } + + public boolean isEmpty() { + return stack.isEmpty(); + } + } +} diff --git a/src/test/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegmentTest.java b/src/test/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegmentTest.java new file mode 100644 index 000000000000..acb9e1e30ac7 --- /dev/null +++ b/src/test/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegmentTest.java @@ -0,0 +1,65 @@ +package com.thealgorithms.slidingwindow; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +/** + * Unit tests for ShortestCoprimeSegment algorithm + * + * @author DomTr (...) + */ +public class ShortestCoprimeSegmentTest { + @Test + public void testShortestCoprimeSegment() { + assertArrayEquals(new long[] {4, 6, 9}, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {4, 6, 9, 3, 6})); + assertArrayEquals(new long[] {4, 5}, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {4, 5, 9, 3, 6})); + assertArrayEquals(new long[] {3, 2}, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {3, 2})); + assertArrayEquals(new long[] {9, 10}, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {3, 9, 9, 9, 10})); + + long[] test5 = new long[] {3 * 11, 11 * 7, 11 * 7 * 3, 11 * 7 * 3 * 5, 11 * 7 * 3 * 5 * 13, 7 * 13, 11 * 7 * 3 * 5 * 13}; + long[] answer5 = Arrays.copyOfRange(test5, 0, test5.length - 1); + assertArrayEquals(answer5, ShortestCoprimeSegment.shortestCoprimeSegment(test5)); + + // Test suite, when the entire array needs to be taken + long[] test6 = new long[] {3 * 7, 7 * 5, 5 * 7 * 3, 3 * 5}; + assertArrayEquals(test6, ShortestCoprimeSegment.shortestCoprimeSegment(test6)); + + long[] test7 = new long[] {3 * 11, 11 * 7, 11 * 7 * 3, 3 * 7}; + assertArrayEquals(test7, ShortestCoprimeSegment.shortestCoprimeSegment(test7)); + + long[] test8 = new long[] {3 * 11, 11 * 7, 11 * 7 * 3, 11 * 7 * 3 * 5, 5 * 7}; + assertArrayEquals(test8, ShortestCoprimeSegment.shortestCoprimeSegment(test8)); + + long[] test9 = new long[] {3 * 11, 11 * 7, 11 * 7 * 3, 11 * 7 * 3 * 5, 11 * 7 * 3 * 5 * 13, 7 * 13}; + assertArrayEquals(test9, ShortestCoprimeSegment.shortestCoprimeSegment(test9)); + + long[] test10 = new long[] {3 * 11, 7 * 11, 3 * 7 * 11, 3 * 5 * 7 * 11, 3 * 5 * 7 * 11 * 13, 2 * 3 * 5 * 7 * 11 * 13, 2 * 3 * 5 * 7 * 11 * 13 * 17, 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19, 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23, 7 * 13}; + assertArrayEquals(test10, ShortestCoprimeSegment.shortestCoprimeSegment(test10)); + + // Segment can consist of one element + long[] test11 = new long[] {1}; + assertArrayEquals(test11, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {4, 6, 1, 3, 6})); + long[] test12 = new long[] {1}; + assertArrayEquals(test12, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {1})); + } + @Test + public void testShortestCoprimeSegment2() { + assertArrayEquals(new long[] {2 * 3, 2 * 3 * 5, 2 * 3 * 5 * 7, 5 * 7}, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {2 * 3, 2 * 3 * 5, 2 * 3 * 5 * 7, 5 * 7, 2 * 3 * 5 * 7})); + assertArrayEquals(new long[] {5 * 7, 2}, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {2 * 3, 2 * 3 * 5, 2 * 3 * 5 * 7, 5 * 7, 2})); + assertArrayEquals(new long[] {5 * 7, 2 * 5 * 7, 2 * 11}, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {2 * 3, 2 * 3 * 5, 2 * 3 * 5 * 7, 5 * 7, 2 * 5 * 7, 2 * 11})); + assertArrayEquals(new long[] {3 * 5 * 7, 2 * 3, 2}, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {2, 2 * 3, 2 * 3 * 5, 3 * 5 * 7, 2 * 3, 2})); + } + @Test + public void testNoCoprimeSegment() { + // There may not be a coprime segment + long[] empty = new long[] {}; + assertArrayEquals(empty, ShortestCoprimeSegment.shortestCoprimeSegment(null)); + assertArrayEquals(empty, ShortestCoprimeSegment.shortestCoprimeSegment(empty)); + assertArrayEquals(empty, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {4, 6, 8, 12, 8})); + assertArrayEquals(empty, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {4, 4, 4, 4, 10, 4, 6, 8, 12, 8})); + assertArrayEquals(empty, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {100})); + assertArrayEquals(empty, ShortestCoprimeSegment.shortestCoprimeSegment(new long[] {2, 2, 2})); + } +} From ae718618eaf3aae55eaa409a36b29b9ab3a633bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Jun 2025 00:18:27 +0200 Subject: [PATCH 097/146] chore(deps): bump com.mebigfatguy.fb-contrib:fb-contrib from 7.6.10 to 7.6.11 (#6297) chore(deps): bump com.mebigfatguy.fb-contrib:fb-contrib Bumps [com.mebigfatguy.fb-contrib:fb-contrib](https://github.com/mebigfatguy/fb-contrib) from 7.6.10 to 7.6.11. - [Commits](https://github.com/mebigfatguy/fb-contrib/commits) --- updated-dependencies: - dependency-name: com.mebigfatguy.fb-contrib:fb-contrib dependency-version: 7.6.11 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a87a7157c2f9..37a8940000c9 100644 --- a/pom.xml +++ b/pom.xml @@ -128,7 +128,7 @@ com.mebigfatguy.fb-contrib fb-contrib - 7.6.10 + 7.6.11 com.h3xstream.findsecbugs From 13d8a28e47c0da3fa157217b84b0cf3fc9765605 Mon Sep 17 00:00:00 2001 From: Rahul <135102753+Rahul-18r@users.noreply.github.com> Date: Sat, 21 Jun 2025 01:37:58 +0530 Subject: [PATCH 098/146] Update DIRECTORY.md with Newly Added Files (#6302) * Update DIRECTORY.md with newly added files * Add files_local.txt to .gitignore * Update .gitignore * Delete .gitignore * Updated .gitignore * Update .gitignore --- DIRECTORY.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index fe9e440da3e2..5cc12315d10b 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -204,6 +204,7 @@ * [RotateSinglyLinkedLists](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java) * [SearchSinglyLinkedListRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java) * [SinglyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java) + * [SinglyLinkedListNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedListNode.java) * [SkipList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java) * [SortedLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SortedLinkedList.java) * [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/Node.java) @@ -233,6 +234,7 @@ * [BSTIterative](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BSTIterative.java) * [BSTRecursive](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursive.java) * [BSTRecursiveGeneric](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java) + * [BTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BTree.java) * [CeilInBinarySearchTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java) * [CheckBinaryTreeIsValidBST](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBST.java) * [CheckIfBinaryTreeBalanced](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java) @@ -302,6 +304,7 @@ * [LongestArithmeticSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java) * [LongestCommonSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java) * [LongestIncreasingSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java) + * [LongestIncreasingSubsequenceNLogN](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogN.java) * [LongestPalindromicSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java) * [LongestPalindromicSubstring](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java) * [LongestValidParentheses](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java) @@ -337,6 +340,7 @@ * graph * [ConstrainedShortestPath](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/graph/ConstrainedShortestPath.java) * [StronglyConnectedComponentOptimized](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/graph/StronglyConnectedComponentOptimized.java) + * [TravelingSalesman](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/graph/TravelingSalesman.java) * greedyalgorithms * [ActivitySelection](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java) * [BandwidthAllocation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/BandwidthAllocation.java) @@ -488,6 +492,7 @@ * [MirrorOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java) * [PrintAMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java) * [RotateMatrixBy90Degrees](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/RotateMatrixBy90Degrees.java) + * [SolveSystem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/SolveSystem.java) * utils * [MatrixUtil](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/utils/MatrixUtil.java) * misc @@ -552,6 +557,11 @@ * [Sudoku](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/puzzlesandgames/Sudoku.java) * [TowerOfHanoi](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/puzzlesandgames/TowerOfHanoi.java) * [WordBoggle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/puzzlesandgames/WordBoggle.java) + * randomized + * [KargerMinCut](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/randomized/KargerMinCut.java) + * [MonteCarloIntegration](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/randomized/MonteCarloIntegration.java) + * [RandomizedQuickSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/randomized/RandomizedQuickSort.java) + * [ReservoirSampling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/randomized/ReservoirSampling.java) * recursion * [FibonacciSeries](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/recursion/FibonacciSeries.java) * [GenerateSubsets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/recursion/GenerateSubsets.java) @@ -618,6 +628,8 @@ * [LongestSubstringWithoutRepeatingCharacters](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java) * [MaxSumKSizeSubarray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarray.java) * [MinSumKSizeSubarray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarray.java) + * [ShortestCoprimeSegment](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegment.java) + * sorts * [AdaptiveMergeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/AdaptiveMergeSort.java) * [BeadSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BeadSort.java) @@ -941,6 +953,7 @@ * [BSTFromSortedArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BSTFromSortedArrayTest.java) * [BSTIterativeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BSTIterativeTest.java) * [BSTRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BSTRecursiveTest.java) + * [BTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BTreeTest.java) * [CeilInBinarySearchTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTreeTest.java) * [CheckBinaryTreeIsValidBSTTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBSTTest.java) * [CheckIfBinaryTreeBalancedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalancedTest.java) @@ -990,6 +1003,7 @@ * [LongestAlternatingSubsequenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequenceTest.java) * [LongestArithmeticSubsequenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequenceTest.java) * [LongestCommonSubsequenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequenceTest.java) + * [LongestIncreasingSubsequenceNLogNTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogNTest.java) * [LongestIncreasingSubsequenceTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java) * [LongestPalindromicSubstringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstringTest.java) * [LongestValidParenthesesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestValidParenthesesTest.java) @@ -1023,7 +1037,9 @@ * [MidpointEllipseTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/geometry/MidpointEllipseTest.java) * graph * [ConstrainedShortestPathTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/graph/ConstrainedShortestPathTest.java) - * [StronglyConnectedComponentOptimizedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/graph/StronglyConnectedComponentOptimizedTest.java) + * [StronglyConnectedComponentOptimizedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/graph/ + * [TravelingSalesmanTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/graph/TravelingSalesmanTest.java) +StronglyConnectedComponentOptimizedTest.java) * greedyalgorithms * [ActivitySelectionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java) * [BandwidthAllocationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/BandwidthAllocationTest.java) @@ -1159,6 +1175,7 @@ * [MatrixUtilTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MatrixUtilTest.java) * [MedianOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MedianOfMatrixTest.java) * [MirrorOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java) + * [SolveSystemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/SolveSystemTest.java) * [TestPrintMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/TestPrintMatrixInSpiralOrder.java) * misc * [ColorContrastRatioTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/ColorContrastRatioTest.java) @@ -1205,6 +1222,11 @@ * [SudokuTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/puzzlesandgames/SudokuTest.java) * [TowerOfHanoiTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/puzzlesandgames/TowerOfHanoiTest.java) * [WordBoggleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/puzzlesandgames/WordBoggleTest.java) + * randomize + * [KargerMinCutTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/randomized/KargerMinCutTest.java) + * [MonteCarloIntegrationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/randomized/MonteCarloIntegrationTest.java) + * [RandomizedQuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/randomized/RandomizedQuickSortTest.java) + * [ReservoirSamplingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java) * recursion * [FibonacciSeriesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/recursion/FibonacciSeriesTest.java) * [GenerateSubsetsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/recursion/GenerateSubsetsTest.java) @@ -1272,6 +1294,7 @@ * [LongestSubstringWithoutRepeatingCharactersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharactersTest.java) * [MaxSumKSizeSubarrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarrayTest.java) * [MinSumKSizeSubarrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarrayTest.java) + * [ShortestCoprimeSegmentTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegmentTest.java) * sorts * [AdaptiveMergeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/AdaptiveMergeSortTest.java) * [BeadSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BeadSortTest.java) @@ -1349,6 +1372,7 @@ * [AlphabeticalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java) * [AnagramsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AnagramsTest.java) * [CharacterSameTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CharacterSameTest.java) + * [CharactersSameTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CharactersSameTest.java) * [CheckAnagramsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CheckAnagramsTest.java) * [CheckVowelsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CheckVowelsTest.java) * [CountCharTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CountCharTest.java) From 83bc063a39dd1c0561ec0d9bf254a2e4f150502f Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Wed, 25 Jun 2025 20:37:06 +0200 Subject: [PATCH 099/146] chore: perform CodeQL scan on actions (#6309) --- .github/workflows/codeql.yml | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a0908a2b57d9..d1133c251b65 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -10,12 +10,9 @@ on: schedule: - cron: '53 3 * * 0' -env: - LANGUAGE: 'java-kotlin' - jobs: - analyze: - name: Analyze + analyzeJava: + name: AnalyzeJava runs-on: 'ubuntu-latest' permissions: actions: read @@ -35,7 +32,7 @@ jobs: - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: - languages: ${{ env.LANGUAGE }} + languages: 'java-kotlin' - name: Build run: mvn --batch-mode --update-snapshots verify @@ -43,5 +40,27 @@ jobs: - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: - category: "/language:${{env.LANGUAGE}}" + category: "/language:java-kotlin" + + analyzeActions: + name: AnalyzeActions + runs-on: 'ubuntu-latest' + permissions: + actions: read + contents: read + security-events: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: 'actions' + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:actions" ... From bb71ae2121cd8a88bfc9119975e5ee9a619edad2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Jun 2025 18:40:36 +0000 Subject: [PATCH 100/146] chore(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.9.3.0 to 4.9.3.1 (#6313) chore(deps): bump com.github.spotbugs:spotbugs-maven-plugin Bumps [com.github.spotbugs:spotbugs-maven-plugin](https://github.com/spotbugs/spotbugs-maven-plugin) from 4.9.3.0 to 4.9.3.1. - [Release notes](https://github.com/spotbugs/spotbugs-maven-plugin/releases) - [Commits](https://github.com/spotbugs/spotbugs-maven-plugin/compare/spotbugs-maven-plugin-4.9.3.0...spotbugs-maven-plugin-4.9.3.1) --- updated-dependencies: - dependency-name: com.github.spotbugs:spotbugs-maven-plugin dependency-version: 4.9.3.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 37a8940000c9..255290e21e40 100644 --- a/pom.xml +++ b/pom.xml @@ -120,7 +120,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.3.0 + 4.9.3.1 spotbugs-exclude.xml true From a91ad201df14c7c75011450cbc737ae4585b930e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Jun 2025 18:43:39 +0000 Subject: [PATCH 101/146] chore(deps): bump org.junit:junit-bom from 5.13.1 to 5.13.2 (#6314) Bumps [org.junit:junit-bom](https://github.com/junit-team/junit-framework) from 5.13.1 to 5.13.2. - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.1...r5.13.2) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-version: 5.13.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 255290e21e40..2619d4d50f28 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ org.junit junit-bom - 5.13.1 + 5.13.2 pom import From 428d259f7c2f08c7f6687fb16f08fcfae8f1c6f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Jun 2025 18:46:54 +0000 Subject: [PATCH 102/146] chore(deps): bump gitpod/workspace-java-21 from 2025-05-14-07-50-25 to 2025-06-18-16-47-14 (#6312) chore(deps): bump gitpod/workspace-java-21 Bumps gitpod/workspace-java-21 from 2025-05-14-07-50-25 to 2025-06-18-16-47-14. --- updated-dependencies: - dependency-name: gitpod/workspace-java-21 dependency-version: 2025-06-18-16-47-14 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .gitpod.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile index 69fee306e1e4..b912ecb35256 100644 --- a/.gitpod.dockerfile +++ b/.gitpod.dockerfile @@ -1,4 +1,4 @@ -FROM gitpod/workspace-java-21:2025-05-14-07-50-25 +FROM gitpod/workspace-java-21:2025-06-18-16-47-14 ENV LLVM_SCRIPT="tmp_llvm.sh" From 5529cb2ca41788f769e38c7c7dcfa2a3e4bb6bcb Mon Sep 17 00:00:00 2001 From: Piotr Idzik <65706193+vil02@users.noreply.github.com> Date: Wed, 25 Jun 2025 22:30:04 +0200 Subject: [PATCH 103/146] chore: explicitly set permissions (#6316) --- .github/workflows/build.yml | 3 +++ .github/workflows/clang-format-lint.yml | 3 +++ .github/workflows/infer.yml | 3 +++ .github/workflows/project_structure.yml | 3 +++ .github/workflows/stale.yml | 5 +++++ 5 files changed, 17 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b3969075d668..3918e89533d5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,9 @@ name: Build on: [push, pull_request] +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/clang-format-lint.yml b/.github/workflows/clang-format-lint.yml index dac697511de1..6f23946db999 100644 --- a/.github/workflows/clang-format-lint.yml +++ b/.github/workflows/clang-format-lint.yml @@ -3,6 +3,9 @@ on: push: {} pull_request: {} +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/infer.yml b/.github/workflows/infer.yml index ffadd13ff3bd..b0ee2fee8243 100644 --- a/.github/workflows/infer.yml +++ b/.github/workflows/infer.yml @@ -8,6 +8,9 @@ name: Infer - master pull_request: +permissions: + contents: read + jobs: run_infer: runs-on: ubuntu-latest diff --git a/.github/workflows/project_structure.yml b/.github/workflows/project_structure.yml index def01554a4f8..dbc725655721 100644 --- a/.github/workflows/project_structure.yml +++ b/.github/workflows/project_structure.yml @@ -8,6 +8,9 @@ name: ProjectStructure - master pull_request: +permissions: + contents: read + jobs: check_structure: runs-on: ubuntu-latest diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 6fb47c5d2dc9..186b3e1d2f5a 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -2,8 +2,13 @@ name: 'Close stale issues and PRs' on: schedule: - cron: '0 0 * * *' +permissions: + contents: read jobs: stale: + permissions: + issues: write + pull-requests: write runs-on: ubuntu-latest steps: - uses: actions/stale@v9 From ba0b0c4176747b8f68bb9ef51287e79d3babbfc3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Jun 2025 20:33:03 +0000 Subject: [PATCH 104/146] chore(deps): bump com.puppycrawl.tools:checkstyle from 10.25.0 to 10.26.0 (#6315) chore(deps): bump com.puppycrawl.tools:checkstyle Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.25.0 to 10.26.0. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.25.0...checkstyle-10.26.0) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 10.26.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2619d4d50f28..afb6ff43ed99 100644 --- a/pom.xml +++ b/pom.xml @@ -113,7 +113,7 @@ com.puppycrawl.tools checkstyle - 10.25.0 + 10.26.0 From a8ad1625170273ee36e82f38d84590b5e3bc8248 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Jun 2025 00:47:39 +0300 Subject: [PATCH 105/146] chore(deps): bump org.apache.maven.plugins:maven-pmd-plugin from 3.26.0 to 3.27.0 (#6317) chore(deps): bump org.apache.maven.plugins:maven-pmd-plugin Bumps [org.apache.maven.plugins:maven-pmd-plugin](https://github.com/apache/maven-pmd-plugin) from 3.26.0 to 3.27.0. - [Release notes](https://github.com/apache/maven-pmd-plugin/releases) - [Commits](https://github.com/apache/maven-pmd-plugin/compare/maven-pmd-plugin-3.26.0...maven-pmd-plugin-3.27.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-pmd-plugin dependency-version: 3.27.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index afb6ff43ed99..1978d12901df 100644 --- a/pom.xml +++ b/pom.xml @@ -141,7 +141,7 @@ org.apache.maven.plugins maven-pmd-plugin - 3.26.0 + 3.27.0 /rulesets/java/maven-pmd-plugin-default.xml From 981d73d02cf3a2caf31d91fd5c393023fb501964 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Jun 2025 16:18:32 +0300 Subject: [PATCH 106/146] chore(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.9.3.1 to 4.9.3.2 (#6319) chore(deps): bump com.github.spotbugs:spotbugs-maven-plugin Bumps [com.github.spotbugs:spotbugs-maven-plugin](https://github.com/spotbugs/spotbugs-maven-plugin) from 4.9.3.1 to 4.9.3.2. - [Release notes](https://github.com/spotbugs/spotbugs-maven-plugin/releases) - [Commits](https://github.com/spotbugs/spotbugs-maven-plugin/compare/spotbugs-maven-plugin-4.9.3.1...spotbugs-maven-plugin-4.9.3.2) --- updated-dependencies: - dependency-name: com.github.spotbugs:spotbugs-maven-plugin dependency-version: 4.9.3.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1978d12901df..0b638c1fc709 100644 --- a/pom.xml +++ b/pom.xml @@ -120,7 +120,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.3.1 + 4.9.3.2 spotbugs-exclude.xml true From 67ccb6246559948485864f287b26937da952e0bf Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Sun, 29 Jun 2025 09:05:51 +0200 Subject: [PATCH 107/146] Modernize GitHub Action to auto-generate DIRECTORY.md (#6308) --- .github/workflows/update-directorymd.yml | 33 +++++++++ .github/workflows/update_directory.yml | 92 ------------------------ 2 files changed, 33 insertions(+), 92 deletions(-) create mode 100644 .github/workflows/update-directorymd.yml delete mode 100644 .github/workflows/update_directory.yml diff --git a/.github/workflows/update-directorymd.yml b/.github/workflows/update-directorymd.yml new file mode 100644 index 000000000000..59b0565f1177 --- /dev/null +++ b/.github/workflows/update-directorymd.yml @@ -0,0 +1,33 @@ +name: Generate Directory Markdown + +on: + push: + branches: [master] + workflow_dispatch: + +permissions: + contents: write + +jobs: + generate-directory: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Run Directory Tree Generator + uses: DenizAltunkapan/directory-tree-generator@v2 + with: + path: src + extensions: .java + show-extensions: false + + - name: Commit and Push DIRECTORY.md + run: | + cat DIRECTORY.md + git config --global user.name "$GITHUB_ACTOR" + git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com" + git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY + git add DIRECTORY.md + git commit -am "Update directory" || true + git push origin HEAD:$GITHUB_REF diff --git a/.github/workflows/update_directory.yml b/.github/workflows/update_directory.yml deleted file mode 100644 index c811d244e54b..000000000000 --- a/.github/workflows/update_directory.yml +++ /dev/null @@ -1,92 +0,0 @@ -# This GitHub Action updates the DIRECTORY.md file (if needed) when doing a git push or pull_request -name: Update Directory -permissions: - contents: write -on: - push: - paths: - - 'src/**' - pull_request: - paths: - - 'src/**' - workflow_dispatch: - inputs: - logLevel: - description: 'Log level' - required: true - default: 'info' - type: choice - options: - - info - - warning - - debug -jobs: - update_directory_md: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - name: Update Directory - shell: python - run: | - import os - from typing import Iterator - - URL_BASE = "https://github.com/TheAlgorithms/Java/blob/master" - g_output = [] - - - def good_filepaths(top_dir: str = ".") -> Iterator[str]: - for dirpath, dirnames, filenames in os.walk(top_dir): - dirnames[:] = [d for d in dirnames if d[0] not in "._"] - for filename in filenames: - if os.path.splitext(filename)[1].lower() == ".java": - yield os.path.join(dirpath, filename).lstrip("./") - - - def md_prefix(i): - return f"{i * ' '}*" if i else "\n##" - - - def print_path(old_path: str, new_path: str) -> str: - global g_output - old_parts = old_path.split(os.sep) - mid_diff = False - new_parts = new_path.split(os.sep) - for i, new_part in enumerate(new_parts): - if i + 1 > len(old_parts) or old_parts[i] != new_part or mid_diff: - if i + 1 < len(new_parts): - mid_diff = True - if new_part: - g_output.append(f"{md_prefix(i)} {new_part.replace('_', ' ')}") - return new_path - - - def build_directory_md(top_dir: str = ".") -> str: - global g_output - old_path = "" - for filepath in sorted(good_filepaths(top_dir), key=str.lower): - filepath, filename = os.path.split(filepath) - if filepath != old_path: - old_path = print_path(old_path, filepath) - indent = (filepath.count(os.sep) + 1) if filepath else 0 - url = "/".join((URL_BASE, filepath, filename)).replace(" ", "%20") - filename = os.path.splitext(filename.replace("_", " "))[0] - g_output.append(f"{md_prefix(indent)} [{filename}]({url})") - return "\n".join(g_output) - - - with open("DIRECTORY.md", "w") as out_file: - out_file.write(build_directory_md(".") + "\n") - - - name: Update DIRECTORY.md - run: | - cat DIRECTORY.md - git config --global user.name "$GITHUB_ACTOR" - git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com" - git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY - git add DIRECTORY.md - git commit -am "Update directory" || true - git push --force origin HEAD:$GITHUB_REF || true From d14873f172440d909926c11b3df3f7a9040aa230 Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Sun, 29 Jun 2025 11:16:02 +0200 Subject: [PATCH 108/146] Automatically create pull requests for directory updates (#6322) --- .github/workflows/update-directorymd.yml | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/update-directorymd.yml b/.github/workflows/update-directorymd.yml index 59b0565f1177..f558cec4fc08 100644 --- a/.github/workflows/update-directorymd.yml +++ b/.github/workflows/update-directorymd.yml @@ -1,4 +1,4 @@ -name: Generate Directory Markdown +name: Generate Directory Markdown on: push: @@ -7,6 +7,7 @@ on: permissions: contents: write + pull-requests: write jobs: generate-directory: @@ -22,12 +23,19 @@ jobs: extensions: .java show-extensions: false - - name: Commit and Push DIRECTORY.md + - name: Commit changes run: | - cat DIRECTORY.md git config --global user.name "$GITHUB_ACTOR" git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com" - git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY git add DIRECTORY.md - git commit -am "Update directory" || true - git push origin HEAD:$GITHUB_REF + git diff --cached --quiet || git commit -m "Update DIRECTORY.md" + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v5 + with: + branch: update-directory + base: master + title: "Update DIRECTORY.md" + body: "Automatically generated update of the directory tree." + commit-message: "Update DIRECTORY.md" + draft: false From e43a1f75e60b97cc4f620e6b3452058812e9845c Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Sun, 29 Jun 2025 13:20:37 +0200 Subject: [PATCH 109/146] Update update-directorymd.yml using PAT (#6324) Update update-directorymd.yml --- .github/workflows/update-directorymd.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/update-directorymd.yml b/.github/workflows/update-directorymd.yml index f558cec4fc08..39269c43d67f 100644 --- a/.github/workflows/update-directorymd.yml +++ b/.github/workflows/update-directorymd.yml @@ -32,6 +32,8 @@ jobs: - name: Create Pull Request uses: peter-evans/create-pull-request@v5 + env: + GITHUB_TOKEN: ${{ secrets.REPO_SCOPED_TOKEN }} with: branch: update-directory base: master From d06fe8b012cfc1a8338b03b9fe5bbfa1ec189fd8 Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Sun, 29 Jun 2025 14:47:07 +0200 Subject: [PATCH 110/146] Update update-directorymd.yml (#6326) --- .github/workflows/update-directorymd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/update-directorymd.yml b/.github/workflows/update-directorymd.yml index 39269c43d67f..4615ef27f830 100644 --- a/.github/workflows/update-directorymd.yml +++ b/.github/workflows/update-directorymd.yml @@ -8,6 +8,7 @@ on: permissions: contents: write pull-requests: write + workflows: write jobs: generate-directory: @@ -32,9 +33,8 @@ jobs: - name: Create Pull Request uses: peter-evans/create-pull-request@v5 - env: - GITHUB_TOKEN: ${{ secrets.REPO_SCOPED_TOKEN }} with: + token: ${{ secrets.REPO_SCOPED_TOKEN }} branch: update-directory base: master title: "Update DIRECTORY.md" From 617412efc021ce7fe3f9653d90416057bcb2c16e Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Sun, 29 Jun 2025 14:57:07 +0200 Subject: [PATCH 111/146] delete workflows from update-directorymd.yml (#6327) --- .github/workflows/update-directorymd.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/update-directorymd.yml b/.github/workflows/update-directorymd.yml index 4615ef27f830..6bc6485f61fb 100644 --- a/.github/workflows/update-directorymd.yml +++ b/.github/workflows/update-directorymd.yml @@ -8,7 +8,6 @@ on: permissions: contents: write pull-requests: write - workflows: write jobs: generate-directory: From 9abf4e38de1b8cf640c9b52600b8b5af7236c7ce Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Mon, 30 Jun 2025 07:17:33 +0200 Subject: [PATCH 112/146] Update DIRECTORY.md (#6328) Co-authored-by: DenizAltunkapan --- DIRECTORY.md | 2815 +++++++++++++++++++++++++------------------------- 1 file changed, 1410 insertions(+), 1405 deletions(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index 5cc12315d10b..7a4c25afe9ca 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -1,1406 +1,1411 @@ +# Project Structure -## src - * main - * java - * com - * thealgorithms - * audiofilters - * [EMAFilter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/audiofilters/EMAFilter.java) - * [IIRFilter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java) - * backtracking - * [AllPathsFromSourceToTarget](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java) - * [ArrayCombination](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java) - * [Combination](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/Combination.java) - * [CrosswordSolver](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/CrosswordSolver.java) - * [FloodFill](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/FloodFill.java) - * [KnightsTour](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/KnightsTour.java) - * [MazeRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java) - * [MColoring](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/MColoring.java) - * [NQueens](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/NQueens.java) - * [ParenthesesGenerator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java) - * [Permutation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/Permutation.java) - * [PowerSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/PowerSum.java) - * [SubsequenceFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java) - * [WordPatternMatcher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/WordPatternMatcher.java) - * [WordSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/WordSearch.java) - * bitmanipulation - * [BcdConversion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/BcdConversion.java) - * [BinaryPalindromeCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheck.java) - * [BitSwap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java) - * [BooleanAlgebraGates](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGates.java) - * [ClearLeftmostSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBit.java) - * [CountLeadingZeros](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/CountLeadingZeros.java) - * [CountSetBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java) - * [FindNthBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/FindNthBit.java) - * [FirstDifferentBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/FirstDifferentBit.java) - * [GenerateSubsets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/GenerateSubsets.java) - * [GrayCodeConversion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/GrayCodeConversion.java) - * [HammingDistance](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/HammingDistance.java) - * [HigherLowerPowerOfTwo](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwo.java) - * [HighestSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java) - * [IndexOfRightMostSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java) - * [IsEven](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java) - * [IsPowerTwo](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java) - * [LowestSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/LowestSetBit.java) - * [ModuloPowerOfTwo](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwo.java) - * [NextHigherSameBitCount](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NextHigherSameBitCount.java) - * [NonRepeatingNumberFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java) - * [NumberAppearingOddTimes](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimes.java) - * [NumbersDifferentSigns](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java) - * [OneBitDifference](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/OneBitDifference.java) - * [OnesComplement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java) - * [ParityCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ParityCheck.java) - * [ReverseBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java) - * [SingleBitOperations](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java) - * [SingleElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SingleElement.java) - * [SwapAdjacentBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SwapAdjacentBits.java) - * [TwosComplement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/TwosComplement.java) - * [Xs3Conversion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/Xs3Conversion.java) - * ciphers - * a5 - * [A5Cipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java) - * [A5KeyStreamGenerator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/A5KeyStreamGenerator.java) - * [BaseLFSR](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/BaseLFSR.java) - * [CompositeLFSR](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java) - * [LFSR](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/LFSR.java) - * [Utils](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/Utils.java) - * [ADFGVXCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ADFGVXCipher.java) - * [AES](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AES.java) - * [AESEncryption](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AESEncryption.java) - * [AffineCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AffineCipher.java) - * [AtbashCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AtbashCipher.java) - * [Autokey](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Autokey.java) - * [BaconianCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/BaconianCipher.java) - * [Blowfish](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Blowfish.java) - * [Caesar](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Caesar.java) - * [ColumnarTranspositionCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java) - * [DES](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/DES.java) - * [DiffieHellman](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/DiffieHellman.java) - * [ECC](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ECC.java) - * [HillCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/HillCipher.java) - * [MonoAlphabetic](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/MonoAlphabetic.java) - * [PlayfairCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java) - * [Polybius](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Polybius.java) - * [ProductCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ProductCipher.java) - * [RailFenceCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java) - * [RSA](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/RSA.java) - * [SimpleSubCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java) - * [Vigenere](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Vigenere.java) - * [XORCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/XORCipher.java) - * conversions - * [AffineConverter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/AffineConverter.java) - * [AnyBaseToAnyBase](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java) - * [AnyBaseToDecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java) - * [AnytoAny](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/AnytoAny.java) - * [BinaryToDecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java) - * [BinaryToHexadecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java) - * [BinaryToOctal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java) - * [DecimalToAnyBase](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java) - * [DecimalToBinary](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java) - * [DecimalToHexadecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/DecimalToHexadecimal.java) - * [DecimalToOctal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java) - * [EndianConverter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/EndianConverter.java) - * [HexaDecimalToBinary](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java) - * [HexaDecimalToDecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java) - * [HexToOct](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/HexToOct.java) - * [IntegerToEnglish](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/IntegerToEnglish.java) - * [IntegerToRoman](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java) - * [IPConverter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/IPConverter.java) - * [IPv6Converter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/IPv6Converter.java) - * [MorseCodeConverter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/MorseCodeConverter.java) - * [NumberToWords](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/NumberToWords.java) - * [OctalToBinary](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/OctalToBinary.java) - * [OctalToDecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java) - * [OctalToHexadecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java) - * [PhoneticAlphabetConverter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/PhoneticAlphabetConverter.java) - * [RgbHsvConversion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java) - * [RomanToInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/RomanToInteger.java) - * [TurkishToLatinConversion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java) - * [UnitConversions](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/UnitConversions.java) - * [UnitsConverter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/UnitsConverter.java) - * [WordsToNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/WordsToNumber.java) - * datastructures - * bags - * [Bag](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/bags/Bag.java) - * bloomfilter - * [BloomFilter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java) - * buffers - * [CircularBuffer](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java) - * caches - * [LFUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java) - * [LRUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java) - * [MRUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java) - * crdt - * [GCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java) - * [GSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java) - * [LWWElementSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java) - * [ORSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java) - * [PNCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java) - * [TwoPSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java) - * disjointsetunion - * [DisjointSetUnion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java) - * [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java) - * dynamicarray - * [DynamicArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java) - * graphs - * [AStar](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/AStar.java) - * [BellmanFord](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java) - * [BipartiteGraphDFS](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java) - * [BoruvkaAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java) - * [ConnectedComponent](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java) - * [Cycles](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java) - * [DijkstraAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithm.java) - * [DijkstraOptimizedAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithm.java) - * [EdmondsBlossomAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithm.java) - * [FloydWarshall](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java) - * [FordFulkerson](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/FordFulkerson.java) - * [Graphs](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java) - * [HamiltonianCycle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java) - * [JohnsonsAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/JohnsonsAlgorithm.java) - * [KahnsAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java) - * [Kosaraju](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/Kosaraju.java) - * [Kruskal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java) - * [MatrixGraphs](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java) - * [PrimMST](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java) - * [TarjansAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java) - * [UndirectedAdjacencyListGraph](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/UndirectedAdjacencyListGraph.java) - * [WelshPowell](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java) - * hashmap - * hashing - * [GenericHashMapUsingArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java) - * [GenericHashMapUsingArrayList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayList.java) - * [HashMap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java) - * [HashMapCuckooHashing](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java) - * [Intersection](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection.java) - * [LinearProbingHashMap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java) - * [MainCuckooHashing](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainCuckooHashing.java) - * [MajorityElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElement.java) - * [Map](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Map.java) - * heaps - * [EmptyHeapException](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java) - * [FibonacciHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/FibonacciHeap.java) - * [GenericHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java) - * [Heap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/Heap.java) - * [HeapElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java) - * [KthElementFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/KthElementFinder.java) - * [LeftistHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java) - * [MaxHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java) - * [MedianFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MedianFinder.java) - * [MergeKSortedArrays](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MergeKSortedArrays.java) - * [MinHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java) - * [MinPriorityQueue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java) - * lists - * [CircleLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java) - * [CountSinglyLinkedListRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java) - * [CreateAndDetectLoop](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java) - * [CursorLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java) - * [DoublyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java) - * [MergeKSortedLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/MergeKSortedLinkedList.java) - * [MergeSortedArrayList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java) - * [MergeSortedSinglyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java) - * [QuickSortLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java) - * [RandomNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/RandomNode.java) - * [ReverseKGroup](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java) - * [RotateSinglyLinkedLists](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java) - * [SearchSinglyLinkedListRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java) - * [SinglyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java) - * [SinglyLinkedListNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedListNode.java) - * [SkipList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java) - * [SortedLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SortedLinkedList.java) - * [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/Node.java) - * queues - * [CircularQueue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java) - * [Deque](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/Deque.java) - * [GenericArrayListQueue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java) - * [LinkedQueue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java) - * [PriorityQueues](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java) - * [Queue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/Queue.java) - * [QueueByTwoStacks](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/QueueByTwoStacks.java) - * [SlidingWindowMaximum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/SlidingWindowMaximum.java) - * [TokenBucket](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/TokenBucket.java) - * stacks - * [NodeStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java) - * [ReverseStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java) - * [Stack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/Stack.java) - * [StackArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/StackArray.java) - * [StackArrayList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/StackArrayList.java) - * [StackOfLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java) - * trees - * [AVLSimple](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java) - * [AVLTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java) - * [BinaryTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java) - * [BoundaryTraversal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BoundaryTraversal.java) - * [BSTFromSortedArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BSTFromSortedArray.java) - * [BSTIterative](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BSTIterative.java) - * [BSTRecursive](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursive.java) - * [BSTRecursiveGeneric](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java) - * [BTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BTree.java) - * [CeilInBinarySearchTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java) - * [CheckBinaryTreeIsValidBST](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBST.java) - * [CheckIfBinaryTreeBalanced](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java) - * [CheckTreeIsSymmetric](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetric.java) - * [CreateBinaryTreeFromInorderPreorder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java) - * [FenwickTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java) - * [GenericTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java) - * [InorderTraversal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/InorderTraversal.java) - * [KDTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/KDTree.java) - * [LazySegmentTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/LazySegmentTree.java) - * [LCA](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/LCA.java) - * [LevelOrderTraversal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java) - * [nearestRightKey](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java) - * [PostOrderTraversal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/PostOrderTraversal.java) - * [PreOrderTraversal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/PreOrderTraversal.java) - * [PrintTopViewofTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java) - * [QuadTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/QuadTree.java) - * [RedBlackBST](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java) - * [SameTreesCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/SameTreesCheck.java) - * [SegmentTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java) - * [SplayTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/SplayTree.java) - * [Treap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/Treap.java) - * [TreeRandomNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/TreeRandomNode.java) - * [Trie](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/Trie.java) - * [VerticalOrderTraversal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java) - * [ZigzagTraversal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java) - * devutils - * entities - * [ProcessDetails](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/entities/ProcessDetails.java) - * nodes - * [LargeTreeNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/nodes/LargeTreeNode.java) - * [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/nodes/Node.java) - * [SimpleNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/nodes/SimpleNode.java) - * [SimpleTreeNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/nodes/SimpleTreeNode.java) - * [TreeNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/nodes/TreeNode.java) - * searches - * [MatrixSearchAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/searches/MatrixSearchAlgorithm.java) - * [SearchAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/searches/SearchAlgorithm.java) - * divideandconquer - * [BinaryExponentiation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java) - * [ClosestPair](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java) - * [CountingInversions](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/CountingInversions.java) - * [MedianOfTwoSortedArrays](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/MedianOfTwoSortedArrays.java) - * [SkylineAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/SkylineAlgorithm.java) - * [StrassenMatrixMultiplication](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java) - * [TilingProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/TilingProblem.java) - * dynamicprogramming - * [Abbreviation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Abbreviation.java) - * [AllConstruct](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/AllConstruct.java) - * [AssignmentUsingBitmask](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java) - * [BoardPath](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java) - * [BoundaryFill](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java) - * [BruteForceKnapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java) - * [CatalanNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java) - * [ClimbingStairs](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/ClimbingStairs.java) - * [CoinChange](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java) - * [CountFriendsPairing](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/CountFriendsPairing.java) - * [DiceThrow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java) - * [EditDistance](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java) - * [EggDropping](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java) - * [Fibonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java) - * [KadaneAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java) - * [Knapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java) - * [KnapsackMemoization](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java) - * [LevenshteinDistance](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java) - * [LongestAlternatingSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java) - * [LongestArithmeticSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java) - * [LongestCommonSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java) - * [LongestIncreasingSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java) - * [LongestIncreasingSubsequenceNLogN](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogN.java) - * [LongestPalindromicSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java) - * [LongestPalindromicSubstring](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java) - * [LongestValidParentheses](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java) - * [MatrixChainMultiplication](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java) - * [MatrixChainRecursiveTopDownMemoisation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java) - * [MaximumSumOfNonAdjacentElements](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/MaximumSumOfNonAdjacentElements.java) - * [MinimumPathSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java) - * [MinimumSumPartition](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java) - * [NewManShanksPrime](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/NewManShanksPrime.java) - * [OptimalJobScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/OptimalJobScheduling.java) - * [PalindromicPartitioning](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java) - * [PartitionProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java) - * [RegexMatching](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java) - * [RodCutting](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java) - * [ShortestCommonSupersequenceLength](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java) - * [SubsetCount](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java) - * [SubsetSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java) - * [SubsetSumSpaceOptimized](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSumSpaceOptimized.java) - * [SumOfSubset](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java) - * [TreeMatching](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/TreeMatching.java) - * [Tribonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java) - * [UniquePaths](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java) - * [UniqueSubsequencesCount](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCount.java) - * [WildcardMatching](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java) - * [WineProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java) - * geometry - * [BresenhamLine](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/geometry/BresenhamLine.java) - * [ConvexHull](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/geometry/ConvexHull.java) - * [GrahamScan](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/geometry/GrahamScan.java) - * [MidpointCircle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/geometry/MidpointCircle.java) - * [MidpointEllipse](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/geometry/MidpointEllipse.java) - * [Point](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/geometry/Point.java) - * graph - * [ConstrainedShortestPath](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/graph/ConstrainedShortestPath.java) - * [StronglyConnectedComponentOptimized](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/graph/StronglyConnectedComponentOptimized.java) - * [TravelingSalesman](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/graph/TravelingSalesman.java) - * greedyalgorithms - * [ActivitySelection](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java) - * [BandwidthAllocation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/BandwidthAllocation.java) - * [BinaryAddition](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/BinaryAddition.java) - * [CoinChange](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java) - * [DigitSeparation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/DigitSeparation.java) - * [EgyptianFraction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/EgyptianFraction.java) - * [FractionalKnapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java) - * [GaleShapley](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/GaleShapley.java) - * [JobSequencing](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java) - * [KCenters](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/KCenters.java) - * [MergeIntervals](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/MergeIntervals.java) - * [MinimizingLateness](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java) - * [MinimumWaitingTime](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/MinimumWaitingTime.java) - * [OptimalFileMerging](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/OptimalFileMerging.java) - * [StockProfitCalculator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/StockProfitCalculator.java) - * io - * [BufferedReader](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/io/BufferedReader.java) - * lineclipping - * [CohenSutherland](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/lineclipping/CohenSutherland.java) - * [LiangBarsky](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/lineclipping/LiangBarsky.java) - * utils - * [Line](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/lineclipping/utils/Line.java) - * [Point](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/lineclipping/utils/Point.java) - * maths - * [AbsoluteMax](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AbsoluteMax.java) - * [AbsoluteMin](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AbsoluteMin.java) - * [AbsoluteValue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AbsoluteValue.java) - * [ADTFraction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/ADTFraction.java) - * [AliquotSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AliquotSum.java) - * [AmicableNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AmicableNumber.java) - * [Area](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Area.java) - * [Armstrong](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Armstrong.java) - * [AutoCorrelation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AutoCorrelation.java) - * [AutomorphicNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AutomorphicNumber.java) - * [Average](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Average.java) - * [BinaryPow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/BinaryPow.java) - * [BinomialCoefficient](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/BinomialCoefficient.java) - * [CatalanNumbers](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/CatalanNumbers.java) - * [Ceil](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Ceil.java) - * [ChineseRemainderTheorem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/ChineseRemainderTheorem.java) - * [CircularConvolutionFFT](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java) - * [CollatzConjecture](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/CollatzConjecture.java) - * [Combinations](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Combinations.java) - * [Convolution](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Convolution.java) - * [ConvolutionFFT](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/ConvolutionFFT.java) - * [CrossCorrelation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/CrossCorrelation.java) - * [DeterminantOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java) - * [DigitalRoot](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/DigitalRoot.java) - * [DistanceFormula](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/DistanceFormula.java) - * [DudeneyNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/DudeneyNumber.java) - * [EulerMethod](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/EulerMethod.java) - * [EulersFunction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/EulersFunction.java) - * [Factorial](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Factorial.java) - * [FactorialRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FactorialRecursion.java) - * [FastExponentiation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FastExponentiation.java) - * [FastInverseSqrt](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FastInverseSqrt.java) - * [FFT](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FFT.java) - * [FFTBluestein](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FFTBluestein.java) - * [FibonacciJavaStreams](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java) - * [FibonacciLoop](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FibonacciLoop.java) - * [FibonacciNumberCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FibonacciNumberCheck.java) - * [FibonacciNumberGoldenRation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java) - * [FindKthNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FindKthNumber.java) - * [FindMax](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FindMax.java) - * [FindMaxRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java) - * [FindMin](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FindMin.java) - * [FindMinRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FindMinRecursion.java) - * [Floor](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Floor.java) - * [FrizzyNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FrizzyNumber.java) - * [Gaussian](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Gaussian.java) - * [GCD](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/GCD.java) - * [GCDRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/GCDRecursion.java) - * [GenericRoot](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/GenericRoot.java) - * [GoldbachConjecture](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/GoldbachConjecture.java) - * [HarshadNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/HarshadNumber.java) - * [HeronsFormula](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/HeronsFormula.java) - * [JosephusProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/JosephusProblem.java) - * [JugglerSequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/JugglerSequence.java) - * [KaprekarNumbers](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/KaprekarNumbers.java) - * [KaratsubaMultiplication](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/KaratsubaMultiplication.java) - * [KeithNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/KeithNumber.java) - * [KrishnamurthyNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java) - * [LeastCommonMultiple](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LeastCommonMultiple.java) - * [LeonardoNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LeonardoNumber.java) - * [LinearDiophantineEquationsSolver](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java) - * [LongDivision](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LongDivision.java) - * [LucasSeries](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LucasSeries.java) - * [MagicSquare](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MagicSquare.java) - * [MathBuilder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MathBuilder.java) - * [MaxValue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MaxValue.java) - * [Means](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Means.java) - * [Median](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Median.java) - * [MinValue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MinValue.java) - * [Mode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Mode.java) - * [NonRepeatingElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/NonRepeatingElement.java) - * [NthUglyNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/NthUglyNumber.java) - * [NumberOfDigits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/NumberOfDigits.java) - * [PalindromeNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PalindromeNumber.java) - * [ParseInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/ParseInteger.java) - * [PascalTriangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PascalTriangle.java) - * [PerfectCube](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PerfectCube.java) - * [PerfectNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PerfectNumber.java) - * [PerfectSquare](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PerfectSquare.java) - * [Perimeter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Perimeter.java) - * [PiNilakantha](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PiNilakantha.java) - * [PollardRho](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PollardRho.java) - * [Pow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Pow.java) - * [PowerOfTwoOrNot](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java) - * [PowerUsingRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java) - * Prime - * [LiouvilleLambdaFunction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Prime/LiouvilleLambdaFunction.java) - * [MillerRabinPrimalityCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Prime/MillerRabinPrimalityCheck.java) - * [MobiusFunction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Prime/MobiusFunction.java) - * [PrimeCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Prime/PrimeCheck.java) - * [PrimeFactorization](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Prime/PrimeFactorization.java) - * [SquareFreeInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Prime/SquareFreeInteger.java) - * [PronicNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PronicNumber.java) - * [PythagoreanTriple](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java) - * [QuadraticEquationSolver](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/QuadraticEquationSolver.java) - * [ReverseNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/ReverseNumber.java) - * [RomanNumeralUtil](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java) - * [SecondMinMax](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SecondMinMax.java) - * [SieveOfEratosthenes](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java) - * [SimpsonIntegration](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java) - * [SolovayStrassenPrimalityTest](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SolovayStrassenPrimalityTest.java) - * [SquareRootWithBabylonianMethod](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java) - * [SquareRootWithNewtonRaphsonMethod](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java) - * [StandardDeviation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/StandardDeviation.java) - * [StandardScore](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/StandardScore.java) - * [StrobogrammaticNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/StrobogrammaticNumber.java) - * [SumOfArithmeticSeries](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SumOfArithmeticSeries.java) - * [SumOfDigits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SumOfDigits.java) - * [SumOfOddNumbers](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SumOfOddNumbers.java) - * [SumWithoutArithmeticOperators](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SumWithoutArithmeticOperators.java) - * [TrinomialTriangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/TrinomialTriangle.java) - * [TwinPrime](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/TwinPrime.java) - * [UniformNumbers](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/UniformNumbers.java) - * [VampireNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/VampireNumber.java) - * [VectorCrossProduct](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/VectorCrossProduct.java) - * [Volume](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Volume.java) - * matrix - * [InverseOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/InverseOfMatrix.java) - * matrixexponentiation - * [Fibonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java) - * [MatrixRank](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/MatrixRank.java) - * [MatrixTranspose](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/MatrixTranspose.java) - * [MedianOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/MedianOfMatrix.java) - * [MirrorOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java) - * [PrintAMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java) - * [RotateMatrixBy90Degrees](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/RotateMatrixBy90Degrees.java) - * [SolveSystem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/SolveSystem.java) - * utils - * [MatrixUtil](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrix/utils/MatrixUtil.java) - * misc - * [ColorContrastRatio](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java) - * [MapReduce](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MapReduce.java) - * [MedianOfRunningArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java) - * [MedianOfRunningArrayByte](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java) - * [MedianOfRunningArrayDouble](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java) - * [MedianOfRunningArrayFloat](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java) - * [MedianOfRunningArrayInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java) - * [MedianOfRunningArrayLong](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java) - * [PalindromePrime](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/PalindromePrime.java) - * [PalindromeSinglyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java) - * [RangeInSortedArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java) - * [ShuffleArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/ShuffleArray.java) - * [Sparsity](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/Sparsity.java) - * [ThreeSumProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/ThreeSumProblem.java) - * [TwoSumProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/TwoSumProblem.java) - * others - * [ArrayLeftRotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ArrayLeftRotation.java) - * [ArrayRightRotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ArrayRightRotation.java) - * [BankersAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/BankersAlgorithm.java) - * [BFPRT](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/BFPRT.java) - * [BoyerMoore](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/BoyerMoore.java) - * [BrianKernighanAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java) - * cn - * [HammingDistance](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/cn/HammingDistance.java) - * [Conway](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Conway.java) - * [CRC16](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/CRC16.java) - * [CRC32](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/CRC32.java) - * [CRCAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/CRCAlgorithm.java) - * [Damm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Damm.java) - * [Dijkstra](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Dijkstra.java) - * [FloydTriangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/FloydTriangle.java) - * [GaussLegendre](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/GaussLegendre.java) - * [HappyNumbersSeq](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/HappyNumbersSeq.java) - * [Huffman](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Huffman.java) - * [Implementing auto completing features using trie](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Implementing_auto_completing_features_using_trie.java) - * [InsertDeleteInArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/InsertDeleteInArray.java) - * [KochSnowflake](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/KochSnowflake.java) - * [Krishnamurthy](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Krishnamurthy.java) - * [LinearCongruentialGenerator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java) - * [LineSweep](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/LineSweep.java) - * [LowestBasePalindrome](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java) - * [Luhn](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Luhn.java) - * [Mandelbrot](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Mandelbrot.java) - * [MaximumSlidingWindow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/MaximumSlidingWindow.java) - * [MaximumSumOfDistinctSubarraysWithLengthK](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthK.java) - * [MemoryManagementAlgorithms](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/MemoryManagementAlgorithms.java) - * [MiniMaxAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java) - * [PageRank](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PageRank.java) - * [PasswordGen](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PasswordGen.java) - * [PerlinNoise](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PerlinNoise.java) - * [PrintAMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java) - * [QueueUsingTwoStacks](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java) - * [RemoveDuplicateFromString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/RemoveDuplicateFromString.java) - * [ReverseStackUsingRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java) - * [SkylineProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/SkylineProblem.java) - * [TwoPointers](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/TwoPointers.java) - * [Verhoeff](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Verhoeff.java) - * puzzlesandgames - * [Sudoku](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/puzzlesandgames/Sudoku.java) - * [TowerOfHanoi](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/puzzlesandgames/TowerOfHanoi.java) - * [WordBoggle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/puzzlesandgames/WordBoggle.java) - * randomized - * [KargerMinCut](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/randomized/KargerMinCut.java) - * [MonteCarloIntegration](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/randomized/MonteCarloIntegration.java) - * [RandomizedQuickSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/randomized/RandomizedQuickSort.java) - * [ReservoirSampling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/randomized/ReservoirSampling.java) - * recursion - * [FibonacciSeries](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/recursion/FibonacciSeries.java) - * [GenerateSubsets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/recursion/GenerateSubsets.java) - * scheduling - * [AgingScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/AgingScheduling.java) - * diskscheduling - * [CircularLookScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/diskscheduling/CircularLookScheduling.java) - * [CircularScanScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/diskscheduling/CircularScanScheduling.java) - * [LookScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/diskscheduling/LookScheduling.java) - * [ScanScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/diskscheduling/ScanScheduling.java) - * [SSFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/diskscheduling/SSFScheduling.java) - * [EDFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/EDFScheduling.java) - * [FairShareScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/FairShareScheduling.java) - * [FCFSScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java) - * [GangScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/GangScheduling.java) - * [HighestResponseRatioNextScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/HighestResponseRatioNextScheduling.java) - * [JobSchedulingWithDeadline](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/JobSchedulingWithDeadline.java) - * [LotteryScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/LotteryScheduling.java) - * [MLFQScheduler](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/MLFQScheduler.java) - * [MultiAgentScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/MultiAgentScheduling.java) - * [NonPreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/NonPreemptivePriorityScheduling.java) - * [PreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java) - * [ProportionalFairScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/ProportionalFairScheduling.java) - * [RandomScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/RandomScheduling.java) - * [RRScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/RRScheduling.java) - * [SelfAdjustingScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SelfAdjustingScheduling.java) - * [SJFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java) - * [SlackTimeScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SlackTimeScheduling.java) - * [SRTFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java) - * searches - * [BinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/BinarySearch.java) - * [BinarySearch2dArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/BinarySearch2dArray.java) - * [BM25InvertedIndex](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/BM25InvertedIndex.java) - * [BreadthFirstSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java) - * [DepthFirstSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/DepthFirstSearch.java) - * [ExponentalSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/ExponentalSearch.java) - * [FibonacciSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/FibonacciSearch.java) - * [HowManyTimesRotated](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java) - * [InterpolationSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/InterpolationSearch.java) - * [IterativeBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java) - * [IterativeTernarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/IterativeTernarySearch.java) - * [JumpSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/JumpSearch.java) - * [KMPSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/KMPSearch.java) - * [LinearSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/LinearSearch.java) - * [LinearSearchThread](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/LinearSearchThread.java) - * [LowerBound](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/LowerBound.java) - * [MonteCarloTreeSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java) - * [OrderAgnosticBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/OrderAgnosticBinarySearch.java) - * [PerfectBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java) - * [QuickSelect](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/QuickSelect.java) - * [RabinKarpAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java) - * [RandomSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RandomSearch.java) - * [RecursiveBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java) - * [RowColumnWiseSorted2dArrayBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java) - * [SaddlebackSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java) - * [SearchInARowAndColWiseSortedMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrix.java) - * [SortOrderAgnosticBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/SortOrderAgnosticBinarySearch.java) - * [SquareRootBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java) - * [TernarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/TernarySearch.java) - * [UnionFind](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/UnionFind.java) - * [UpperBound](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/UpperBound.java) - * slidingwindow - * [LongestSubarrayWithSumLessOrEqualToK](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/LongestSubarrayWithSumLessOrEqualToK.java) - * [LongestSubstringWithoutRepeatingCharacters](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java) - * [MaxSumKSizeSubarray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarray.java) - * [MinSumKSizeSubarray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarray.java) - * [ShortestCoprimeSegment](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegment.java) - - * sorts - * [AdaptiveMergeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/AdaptiveMergeSort.java) - * [BeadSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BeadSort.java) - * [BinaryInsertionSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java) - * [BitonicSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BitonicSort.java) - * [BogoSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BogoSort.java) - * [BubbleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BubbleSort.java) - * [BubbleSortRecursive](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BubbleSortRecursive.java) - * [BucketSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BucketSort.java) - * [CircleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CircleSort.java) - * [CocktailShakerSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java) - * [CombSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CombSort.java) - * [CountingSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CountingSort.java) - * [CycleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CycleSort.java) - * [DarkSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DarkSort.java) - * [DualPivotQuickSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java) - * [DutchNationalFlagSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java) - * [ExchangeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/ExchangeSort.java) - * [FlashSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/FlashSort.java) - * [GnomeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/GnomeSort.java) - * [HeapSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/HeapSort.java) - * [InsertionSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/InsertionSort.java) - * [IntrospectiveSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/IntrospectiveSort.java) - * [LinkListSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/LinkListSort.java) - * [MergeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/MergeSort.java) - * [MergeSortNoExtraSpace](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java) - * [MergeSortRecursive](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java) - * [OddEvenSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/OddEvenSort.java) - * [PancakeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PancakeSort.java) - * [PatienceSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PatienceSort.java) - * [PigeonholeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java) - * [QuickSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/QuickSort.java) - * [RadixSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/RadixSort.java) - * [SelectionSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SelectionSort.java) - * [SelectionSortRecursive](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SelectionSortRecursive.java) - * [ShellSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/ShellSort.java) - * [SimpleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SimpleSort.java) - * [SlowSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SlowSort.java) - * [SortAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SortAlgorithm.java) - * [SortUtils](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SortUtils.java) - * [SortUtilsRandomGenerator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SortUtilsRandomGenerator.java) - * [SpreadSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SpreadSort.java) - * [StalinSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/StalinSort.java) - * [StoogeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/StoogeSort.java) - * [StrandSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/StrandSort.java) - * [SwapSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SwapSort.java) - * [TimSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/TimSort.java) - * [TopologicalSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/TopologicalSort.java) - * [TreeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/TreeSort.java) - * [WaveSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/WaveSort.java) - * [WiggleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/WiggleSort.java) - * stacks - * [BalancedBrackets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java) - * [CelebrityFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/CelebrityFinder.java) - * [DecimalToAnyUsingStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java) - * [DuplicateBrackets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java) - * [GreatestElementConstantTime](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/GreatestElementConstantTime.java) - * [InfixToPostfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java) - * [InfixToPrefix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/InfixToPrefix.java) - * [LargestRectangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/LargestRectangle.java) - * [MaximumMinimumWindow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java) - * [MinStackUsingSingleStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/MinStackUsingSingleStack.java) - * [MinStackUsingTwoStacks](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/MinStackUsingTwoStacks.java) - * [NextGreaterElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java) - * [NextSmallerElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java) - * [PalindromeWithStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PalindromeWithStack.java) - * [PostfixEvaluator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PostfixEvaluator.java) - * [PostfixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java) - * [PrefixEvaluator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PrefixEvaluator.java) - * [PrefixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java) - * [SmallestElementConstantTime](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/SmallestElementConstantTime.java) - * [SortStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/SortStack.java) - * [StackPostfixNotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java) - * [StackUsingTwoQueues](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/StackUsingTwoQueues.java) - * strings - * [AhoCorasick](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/AhoCorasick.java) - * [Alphabetical](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Alphabetical.java) - * [Anagrams](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Anagrams.java) - * [CharactersSame](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/CharactersSame.java) - * [CheckAnagrams](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/CheckAnagrams.java) - * [CheckVowels](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/CheckVowels.java) - * [CountChar](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/CountChar.java) - * [CountWords](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/CountWords.java) - * [HammingDistance](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/HammingDistance.java) - * [HorspoolSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/HorspoolSearch.java) - * [Isomorphic](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Isomorphic.java) - * [KMP](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/KMP.java) - * [LetterCombinationsOfPhoneNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumber.java) - * [LongestCommonPrefix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/LongestCommonPrefix.java) - * [LongestNonRepetitiveSubstring](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/LongestNonRepetitiveSubstring.java) - * [LongestPalindromicSubstring](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java) - * [Lower](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Lower.java) - * [Manacher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Manacher.java) - * [MyAtoi](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/MyAtoi.java) - * [Palindrome](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Palindrome.java) - * [Pangram](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Pangram.java) - * [PermuteString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/PermuteString.java) - * [RabinKarp](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/RabinKarp.java) - * [ReturnSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/ReturnSubsequence.java) - * [ReverseString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/ReverseString.java) - * [ReverseStringRecursive](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/ReverseStringRecursive.java) - * [ReverseWordsInString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/ReverseWordsInString.java) - * [Rotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Rotation.java) - * [StringCompression](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/StringCompression.java) - * [StringMatchFiniteAutomata](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/StringMatchFiniteAutomata.java) - * [Upper](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Upper.java) - * [ValidParentheses](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/ValidParentheses.java) - * [WordLadder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/WordLadder.java) - * zigZagPattern - * [ZigZagPattern](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/zigZagPattern/ZigZagPattern.java) - * tree - * [HeavyLightDecomposition](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/tree/HeavyLightDecomposition.java) - * test - * java - * com - * thealgorithms - * audiofilters - * [EMAFilterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/audiofilters/EMAFilterTest.java) - * [IIRFilterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/audiofilters/IIRFilterTest.java) - * backtracking - * [AllPathsFromSourceToTargetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java) - * [ArrayCombinationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java) - * [CombinationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/CombinationTest.java) - * [CrosswordSolverTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/CrosswordSolverTest.java) - * [FloodFillTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/FloodFillTest.java) - * [KnightsTourTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/KnightsTourTest.java) - * [MazeRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/MazeRecursionTest.java) - * [MColoringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/MColoringTest.java) - * [NQueensTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/NQueensTest.java) - * [ParenthesesGeneratorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/ParenthesesGeneratorTest.java) - * [PermutationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/PermutationTest.java) - * [PowerSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/PowerSumTest.java) - * [SubsequenceFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/SubsequenceFinderTest.java) - * [WordPatternMatcherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/WordPatternMatcherTest.java) - * [WordSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/WordSearchTest.java) - * bitmanipulation - * [BcdConversionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/BcdConversionTest.java) - * [BinaryPalindromeCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheckTest.java) - * [BitSwapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java) - * [BooleanAlgebraGatesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGatesTest.java) - * [ClearLeftmostSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBitTest.java) - * [CountLeadingZerosTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/CountLeadingZerosTest.java) - * [CountSetBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/CountSetBitsTest.java) - * [FindNthBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/FindNthBitTest.java) - * [FirstDifferentBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/FirstDifferentBitTest.java) - * [GenerateSubsetsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/GenerateSubsetsTest.java) - * [GrayCodeConversionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/GrayCodeConversionTest.java) - * [HammingDistanceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/HammingDistanceTest.java) - * [HigherLowerPowerOfTwoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwoTest.java) - * [HighestSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java) - * [IndexOfRightMostSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java) - * [IsEvenTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java) - * [IsPowerTwoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java) - * [LowestSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/LowestSetBitTest.java) - * [ModuloPowerOfTwoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwoTest.java) - * [NextHigherSameBitCountTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NextHigherSameBitCountTest.java) - * [NonRepeatingNumberFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java) - * [NumberAppearingOddTimesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimesTest.java) - * [NumbersDifferentSignsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java) - * [OneBitDifferenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/OneBitDifferenceTest.java) - * [OnesComplementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/OnesComplementTest.java) - * [ParityCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ParityCheckTest.java) - * [ReverseBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java) - * [SingleBitOperationsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java) - * [SingleElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SingleElementTest.java) - * [SwapAdjacentBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SwapAdjacentBitsTest.java) - * [TwosComplementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/TwosComplementTest.java) - * [Xs3ConversionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/Xs3ConversionTest.java) - * ciphers - * a5 - * [A5CipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/A5CipherTest.java) - * [A5KeyStreamGeneratorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/A5KeyStreamGeneratorTest.java) - * [LFSRTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java) - * [ADFGVXCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/ADFGVXCipherTest.java) - * [AESEncryptionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AESEncryptionTest.java) - * [AffineCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AffineCipherTest.java) - * [AtbashTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AtbashTest.java) - * [AutokeyTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AutokeyTest.java) - * [BaconianCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/BaconianCipherTest.java) - * [BlowfishTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java) - * [CaesarTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/CaesarTest.java) - * [ColumnarTranspositionCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherTest.java) - * [DESTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/DESTest.java) - * [DiffieHellmanTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/DiffieHellmanTest.java) - * [ECCTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/ECCTest.java) - * [HillCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/HillCipherTest.java) - * [MonoAlphabeticTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/MonoAlphabeticTest.java) - * [PlayfairTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java) - * [PolybiusTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PolybiusTest.java) - * [RailFenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/RailFenceTest.java) - * [RSATest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/RSATest.java) - * [SimpleSubCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherTest.java) - * [VigenereTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/VigenereTest.java) - * [XORCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/XORCipherTest.java) - * conversions - * [AffineConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/AffineConverterTest.java) - * [AnyBaseToDecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/AnyBaseToDecimalTest.java) - * [AnytoAnyTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/AnytoAnyTest.java) - * [BinaryToDecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/BinaryToDecimalTest.java) - * [BinaryToHexadecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/BinaryToHexadecimalTest.java) - * [BinaryToOctalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/BinaryToOctalTest.java) - * [DecimalToAnyBaseTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/DecimalToAnyBaseTest.java) - * [DecimalToBinaryTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/DecimalToBinaryTest.java) - * [DecimalToHexadecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/DecimalToHexadecimalTest.java) - * [DecimalToOctalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/DecimalToOctalTest.java) - * [EndianConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/EndianConverterTest.java) - * [HexaDecimalToBinaryTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/HexaDecimalToBinaryTest.java) - * [HexaDecimalToDecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/HexaDecimalToDecimalTest.java) - * [HexToOctTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/HexToOctTest.java) - * [IntegerToEnglishTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/IntegerToEnglishTest.java) - * [IntegerToRomanTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/IntegerToRomanTest.java) - * [IPConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/IPConverterTest.java) - * [IPv6ConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/IPv6ConverterTest.java) - * [MorseCodeConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/MorseCodeConverterTest.java) - * [NumberToWordsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/NumberToWordsTest.java) - * [OctalToBinaryTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java) - * [OctalToDecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java) - * [OctalToHexadecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/OctalToHexadecimalTest.java) - * [PhoneticAlphabetConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/PhoneticAlphabetConverterTest.java) - * [RomanToIntegerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/RomanToIntegerTest.java) - * [TurkishToLatinConversionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/TurkishToLatinConversionTest.java) - * [UnitConversionsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/UnitConversionsTest.java) - * [UnitsConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/UnitsConverterTest.java) - * [WordsToNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/WordsToNumberTest.java) - * datastructures - * bag - * [BagTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/bag/BagTest.java) - * bloomfilter - * [BloomFilterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/bloomfilter/BloomFilterTest.java) - * buffers - * [CircularBufferTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/buffers/CircularBufferTest.java) - * caches - * [LFUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/LFUCacheTest.java) - * [LRUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java) - * [MRUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java) - * crdt - * [GCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java) - * [GSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java) - * [LWWElementSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java) - * [ORSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java) - * [PNCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java) - * [TwoPSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java) - * disjointsetunion - * [DisjointSetUnionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java) - * dynamicarray - * [DynamicArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/dynamicarray/DynamicArrayTest.java) - * graphs - * [AStarTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/AStarTest.java) - * [BipartiteGraphDFSTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java) - * [BoruvkaAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java) - * [DijkstraAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java) - * [DijkstraOptimizedAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithmTest.java) - * [EdmondsBlossomAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithmTest.java) - * [FloydWarshallTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/FloydWarshallTest.java) - * [FordFulkersonTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/FordFulkersonTest.java) - * [HamiltonianCycleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java) - * [JohnsonsAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/JohnsonsAlgorithmTest.java) - * [KahnsAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithmTest.java) - * [KosarajuTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/KosarajuTest.java) - * [KruskalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/KruskalTest.java) - * [MatrixGraphsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/MatrixGraphsTest.java) - * [PrimMSTTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/PrimMSTTest.java) - * [TarjansAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithmTest.java) - * [WelshPowellTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java) - * hashmap - * hashing - * [GenericHashMapUsingArrayListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayListTest.java) - * [GenericHashMapUsingArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayTest.java) - * [HashMapCuckooHashingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashingTest.java) - * [HashMapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapTest.java) - * [IntersectionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/IntersectionTest.java) - * [LinearProbingHashMapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMapTest.java) - * [MajorityElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElementTest.java) - * [MapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MapTest.java) - * heaps - * [FibonacciHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/FibonacciHeapTest.java) - * [GenericHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/GenericHeapTest.java) - * [HeapElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/HeapElementTest.java) - * [KthElementFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/KthElementFinderTest.java) - * [LeftistHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java) - * [MaxHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MaxHeapTest.java) - * [MedianFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MedianFinderTest.java) - * [MergeKSortedArraysTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MergeKSortedArraysTest.java) - * [MinHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MinHeapTest.java) - * [MinPriorityQueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MinPriorityQueueTest.java) - * lists - * [CircleLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java) - * [CountSinglyLinkedListRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursionTest.java) - * [CreateAndDetectLoopTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoopTest.java) - * [CursorLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CursorLinkedListTest.java) - * [MergeKSortedLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/MergeKSortedLinkedListTest.java) - * [MergeSortedArrayListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/MergeSortedArrayListTest.java) - * [MergeSortedSinglyLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedListTest.java) - * [QuickSortLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java) - * [ReverseKGroupTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java) - * [RotateSinglyLinkedListsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java) - * [SearchSinglyLinkedListRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursionTest.java) - * [SinglyLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java) - * [SkipListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java) - * [SortedLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/SortedLinkedListTest.java) - * queues - * [CircularQueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/CircularQueueTest.java) - * [DequeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/DequeTest.java) - * [GenericArrayListQueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/GenericArrayListQueueTest.java) - * [LinkedQueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/LinkedQueueTest.java) - * [PriorityQueuesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/PriorityQueuesTest.java) - * [QueueByTwoStacksTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/QueueByTwoStacksTest.java) - * [QueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/QueueTest.java) - * [SlidingWindowMaximumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/SlidingWindowMaximumTest.java) - * [TokenBucketTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/TokenBucketTest.java) - * stacks - * [NodeStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/NodeStackTest.java) - * [ReverseStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/ReverseStackTest.java) - * [StackArrayListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackArrayListTest.java) - * [StackArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackArrayTest.java) - * [StackOfLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackOfLinkedListTest.java) - * trees - * [AVLTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/AVLTreeTest.java) - * [BinaryTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeTest.java) - * [BoundaryTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BoundaryTraversalTest.java) - * [BSTFromSortedArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BSTFromSortedArrayTest.java) - * [BSTIterativeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BSTIterativeTest.java) - * [BSTRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BSTRecursiveTest.java) - * [BTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BTreeTest.java) - * [CeilInBinarySearchTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTreeTest.java) - * [CheckBinaryTreeIsValidBSTTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBSTTest.java) - * [CheckIfBinaryTreeBalancedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalancedTest.java) - * [CheckTreeIsSymmetricTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetricTest.java) - * [CreateBinaryTreeFromInorderPreorderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorderTest.java) - * [InorderTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/InorderTraversalTest.java) - * [KDTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/KDTreeTest.java) - * [LazySegmentTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java) - * [LevelOrderTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/LevelOrderTraversalTest.java) - * [PostOrderTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/PostOrderTraversalTest.java) - * [PreOrderTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/PreOrderTraversalTest.java) - * [QuadTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/QuadTreeTest.java) - * [SameTreesCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/SameTreesCheckTest.java) - * [SplayTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/SplayTreeTest.java) - * [TreapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java) - * [TreeTestUtils](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/TreeTestUtils.java) - * [TrieTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/TrieTest.java) - * [VerticalOrderTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversalTest.java) - * [ZigzagTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/ZigzagTraversalTest.java) - * divideandconquer - * [BinaryExponentiationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/BinaryExponentiationTest.java) - * [ClosestPairTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/ClosestPairTest.java) - * [CountingInversionsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/CountingInversionsTest.java) - * [MedianOfTwoSortedArraysTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/MedianOfTwoSortedArraysTest.java) - * [SkylineAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/SkylineAlgorithmTest.java) - * [StrassenMatrixMultiplicationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java) - * [TilingProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/TilingProblemTest.java) - * dynamicprogramming - * [AbbreviationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/AbbreviationTest.java) - * [AllConstructTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/AllConstructTest.java) - * [AssignmentUsingBitmaskTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java) - * [BoardPathTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BoardPathTest.java) - * [BoundaryFillTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BoundaryFillTest.java) - * [BruteForceKnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java) - * [CatalanNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java) - * [ClimbStairsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/ClimbStairsTest.java) - * [CoinChangeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/CoinChangeTest.java) - * [CountFriendsPairingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/CountFriendsPairingTest.java) - * [DPTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/DPTest.java) - * [EditDistanceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/EditDistanceTest.java) - * [EggDroppingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/EggDroppingTest.java) - * [FibonacciTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/FibonacciTest.java) - * [KadaneAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithmTest.java) - * [KnapsackMemoizationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java) - * [KnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java) - * [LevenshteinDistanceTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java) - * [LongestAlternatingSubsequenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequenceTest.java) - * [LongestArithmeticSubsequenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequenceTest.java) - * [LongestCommonSubsequenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequenceTest.java) - * [LongestIncreasingSubsequenceNLogNTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogNTest.java) - * [LongestIncreasingSubsequenceTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java) - * [LongestPalindromicSubstringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstringTest.java) - * [LongestValidParenthesesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestValidParenthesesTest.java) - * [MatrixChainMultiplicationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplicationTest.java) - * [MatrixChainRecursiveTopDownMemoisationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisationTest.java) - * [MaximumSumOfNonAdjacentElementsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/MaximumSumOfNonAdjacentElementsTest.java) - * [MinimumPathSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java) - * [MinimumSumPartitionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java) - * [NewManShanksPrimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/NewManShanksPrimeTest.java) - * [OptimalJobSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java) - * [PalindromicPartitioningTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioningTest.java) - * [PartitionProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java) - * [RegexMatchingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/RegexMatchingTest.java) - * [RodCuttingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/RodCuttingTest.java) - * [ShortestCommonSupersequenceLengthTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLengthTest.java) - * [SubsetCountTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java) - * [SubsetSumSpaceOptimizedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SubsetSumSpaceOptimizedTest.java) - * [SubsetSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SubsetSumTest.java) - * [SumOfSubsetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java) - * [TreeMatchingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/TreeMatchingTest.java) - * [TribonacciTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java) - * [UniquePathsTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java) - * [UniqueSubsequencesCountTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCountTest.java) - * [WildcardMatchingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java) - * [WineProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/WineProblemTest.java) - * geometry - * [BresenhamLineTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/geometry/BresenhamLineTest.java) - * [ConvexHullTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/geometry/ConvexHullTest.java) - * [GrahamScanTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/geometry/GrahamScanTest.java) - * [MidpointCircleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/geometry/MidpointCircleTest.java) - * [MidpointEllipseTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/geometry/MidpointEllipseTest.java) - * graph - * [ConstrainedShortestPathTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/graph/ConstrainedShortestPathTest.java) - * [StronglyConnectedComponentOptimizedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/graph/ - * [TravelingSalesmanTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/graph/TravelingSalesmanTest.java) -StronglyConnectedComponentOptimizedTest.java) - * greedyalgorithms - * [ActivitySelectionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java) - * [BandwidthAllocationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/BandwidthAllocationTest.java) - * [BinaryAdditionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/BinaryAdditionTest.java) - * [CoinChangeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeTest.java) - * [DigitSeparationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/DigitSeparationTest.java) - * [EgyptianFractionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/EgyptianFractionTest.java) - * [FractionalKnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java) - * [GaleShapleyTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/GaleShapleyTest.java) - * [JobSequencingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java) - * [KCentersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/KCentersTest.java) - * [MergeIntervalsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/MergeIntervalsTest.java) - * [MinimizingLatenessTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java) - * [MinimumWaitingTimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/MinimumWaitingTimeTest.java) - * [OptimalFileMergingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/OptimalFileMergingTest.java) - * [StockProfitCalculatorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/StockProfitCalculatorTest.java) - * io - * [BufferedReaderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/io/BufferedReaderTest.java) - * lineclipping - * [CohenSutherlandTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/lineclipping/CohenSutherlandTest.java) - * [LiangBarskyTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/lineclipping/LiangBarskyTest.java) - * maths - * [AbsoluteMaxTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AbsoluteMaxTest.java) - * [AbsoluteMinTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AbsoluteMinTest.java) - * [AbsoluteValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AbsoluteValueTest.java) - * [ADTFractionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ADTFractionTest.java) - * [AliquotSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AliquotSumTest.java) - * [AmicableNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AmicableNumberTest.java) - * [AreaTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AreaTest.java) - * [ArmstrongTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ArmstrongTest.java) - * [AutoCorrelationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AutoCorrelationTest.java) - * [AutomorphicNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AutomorphicNumberTest.java) - * [AverageTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AverageTest.java) - * [BinaryPowTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/BinaryPowTest.java) - * [BinomialCoefficientTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/BinomialCoefficientTest.java) - * [CatalanNumbersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/CatalanNumbersTest.java) - * [CeilTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/CeilTest.java) - * [ChineseRemainderTheoremTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ChineseRemainderTheoremTest.java) - * [CollatzConjectureTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/CollatzConjectureTest.java) - * [CombinationsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/CombinationsTest.java) - * [ConvolutionFFTTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ConvolutionFFTTest.java) - * [ConvolutionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ConvolutionTest.java) - * [CrossCorrelationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/CrossCorrelationTest.java) - * [DeterminantOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/DeterminantOfMatrixTest.java) - * [DigitalRootTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/DigitalRootTest.java) - * [DistanceFormulaTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/DistanceFormulaTest.java) - * [DudeneyNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/DudeneyNumberTest.java) - * [EulerMethodTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/EulerMethodTest.java) - * [EulersFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/EulersFunctionTest.java) - * [FactorialRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FactorialRecursionTest.java) - * [FactorialTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FactorialTest.java) - * [FastExponentiationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FastExponentiationTest.java) - * [FastInverseSqrtTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java) - * [FFTTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FFTTest.java) - * [FibonacciJavaStreamsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java) - * [FibonacciLoopTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciLoopTest.java) - * [FibonacciNumberCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciNumberCheckTest.java) - * [FibonacciNumberGoldenRationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciNumberGoldenRationTest.java) - * [FindKthNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindKthNumberTest.java) - * [FindMaxRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java) - * [FindMaxTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMaxTest.java) - * [FindMinRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java) - * [FindMinTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMinTest.java) - * [FloorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FloorTest.java) - * [FrizzyNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FrizzyNumberTest.java) - * [GaussianTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GaussianTest.java) - * [GCDRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GCDRecursionTest.java) - * [GCDTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GCDTest.java) - * [GenericRootTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GenericRootTest.java) - * [GoldbachConjectureTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GoldbachConjectureTest.java) - * [HarshadNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/HarshadNumberTest.java) - * [HeronsFormulaTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java) - * [JosephusProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/JosephusProblemTest.java) - * [KaprekarNumbersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java) - * [KaratsubaMultiplicationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/KaratsubaMultiplicationTest.java) - * [KrishnamurthyNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/KrishnamurthyNumberTest.java) - * [LeastCommonMultipleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LeastCommonMultipleTest.java) - * [LeonardoNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LeonardoNumberTest.java) - * [LongDivisionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LongDivisionTest.java) - * [LucasSeriesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LucasSeriesTest.java) - * [MathBuilderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MathBuilderTest.java) - * [MaxValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MaxValueTest.java) - * [MeansTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MeansTest.java) - * [MedianTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MedianTest.java) - * [MinValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MinValueTest.java) - * [ModeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ModeTest.java) - * [NonRepeatingElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/NonRepeatingElementTest.java) - * [NthUglyNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/NthUglyNumberTest.java) - * [NumberOfDigitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java) - * [PalindromeNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PalindromeNumberTest.java) - * [ParseIntegerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ParseIntegerTest.java) - * [PascalTriangleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PascalTriangleTest.java) - * [PerfectCubeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PerfectCubeTest.java) - * [PerfectNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PerfectNumberTest.java) - * [PerfectSquareTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PerfectSquareTest.java) - * [PerimeterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PerimeterTest.java) - * [PollardRhoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PollardRhoTest.java) - * [PowerOfTwoOrNotTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java) - * [PowerUsingRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java) - * [PowTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PowTest.java) - * prime - * [LiouvilleLambdaFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/prime/LiouvilleLambdaFunctionTest.java) - * [MillerRabinPrimalityCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/prime/MillerRabinPrimalityCheckTest.java) - * [MobiusFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/prime/MobiusFunctionTest.java) - * [PrimeCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/prime/PrimeCheckTest.java) - * [PrimeFactorizationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/prime/PrimeFactorizationTest.java) - * [PronicNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PronicNumberTest.java) - * [PythagoreanTripleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java) - * [QuadraticEquationSolverTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/QuadraticEquationSolverTest.java) - * [ReverseNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ReverseNumberTest.java) - * [SecondMinMaxTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java) - * [SieveOfEratosthenesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java) - * [SolovayStrassenPrimalityTestTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SolovayStrassenPrimalityTestTest.java) - * [SquareFreeIntegerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java) - * [SquareRootwithBabylonianMethodTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java) - * [SquareRootWithNewtonRaphsonTestMethod](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonTestMethod.java) - * [StandardDeviationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/StandardDeviationTest.java) - * [StandardScoreTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/StandardScoreTest.java) - * [StrobogrammaticNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/StrobogrammaticNumberTest.java) - * [SumOfArithmeticSeriesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SumOfArithmeticSeriesTest.java) - * [SumOfDigitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SumOfDigitsTest.java) - * [SumOfOddNumbersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SumOfOddNumbersTest.java) - * [SumWithoutArithmeticOperatorsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SumWithoutArithmeticOperatorsTest.java) - * [TestArmstrong](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/TestArmstrong.java) - * [TwinPrimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/TwinPrimeTest.java) - * [UniformNumbersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/UniformNumbersTest.java) - * [VampireNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/VampireNumberTest.java) - * [VolumeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/VolumeTest.java) - * matrix - * [InverseOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/InverseOfMatrixTest.java) - * [MatrixRankTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MatrixRankTest.java) - * [MatrixTransposeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MatrixTransposeTest.java) - * [MatrixUtilTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MatrixUtilTest.java) - * [MedianOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MedianOfMatrixTest.java) - * [MirrorOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java) - * [SolveSystemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/SolveSystemTest.java) - * [TestPrintMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/matrix/TestPrintMatrixInSpiralOrder.java) - * misc - * [ColorContrastRatioTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/ColorContrastRatioTest.java) - * [MapReduceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MapReduceTest.java) - * [MedianOfRunningArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java) - * [PalindromePrimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/PalindromePrimeTest.java) - * [PalindromeSinglyLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/PalindromeSinglyLinkedListTest.java) - * [RangeInSortedArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/RangeInSortedArrayTest.java) - * [ShuffleArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/ShuffleArrayTest.java) - * [SparsityTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/SparsityTest.java) - * [ThreeSumProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/ThreeSumProblemTest.java) - * [TwoSumProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/TwoSumProblemTest.java) - * others - * [ArrayLeftRotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java) - * [ArrayRightRotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ArrayRightRotationTest.java) - * [BestFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/BestFitCPUTest.java) - * [BFPRTTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/BFPRTTest.java) - * [BoyerMooreTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/BoyerMooreTest.java) - * cn - * [HammingDistanceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/cn/HammingDistanceTest.java) - * [ConwayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ConwayTest.java) - * [CountFriendsPairingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/CountFriendsPairingTest.java) - * [CRC16Test](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/CRC16Test.java) - * [CRCAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/CRCAlgorithmTest.java) - * [FirstFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/FirstFitCPUTest.java) - * [FloydTriangleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/FloydTriangleTest.java) - * [KadaneAlogrithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/KadaneAlogrithmTest.java) - * [LineSweepTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/LineSweepTest.java) - * [LinkListSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/LinkListSortTest.java) - * [LowestBasePalindromeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/LowestBasePalindromeTest.java) - * [MaximumSlidingWindowTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/MaximumSlidingWindowTest.java) - * [MaximumSumOfDistinctSubarraysWithLengthKTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthKTest.java) - * [NewManShanksPrimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/NewManShanksPrimeTest.java) - * [NextFitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/NextFitTest.java) - * [PasswordGenTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/PasswordGenTest.java) - * [QueueUsingTwoStacksTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/QueueUsingTwoStacksTest.java) - * [RemoveDuplicateFromStringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/RemoveDuplicateFromStringTest.java) - * [ReverseStackUsingRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ReverseStackUsingRecursionTest.java) - * [SkylineProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/SkylineProblemTest.java) - * [TestPrintMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java) - * [TwoPointersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TwoPointersTest.java) - * [WorstFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java) - * puzzlesandgames - * [SudokuTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/puzzlesandgames/SudokuTest.java) - * [TowerOfHanoiTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/puzzlesandgames/TowerOfHanoiTest.java) - * [WordBoggleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/puzzlesandgames/WordBoggleTest.java) - * randomize - * [KargerMinCutTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/randomized/KargerMinCutTest.java) - * [MonteCarloIntegrationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/randomized/MonteCarloIntegrationTest.java) - * [RandomizedQuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/randomized/RandomizedQuickSortTest.java) - * [ReservoirSamplingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java) - * recursion - * [FibonacciSeriesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/recursion/FibonacciSeriesTest.java) - * [GenerateSubsetsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/recursion/GenerateSubsetsTest.java) - * scheduling - * [AgingSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/AgingSchedulingTest.java) - * diskscheduling - * [CircularLookSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/diskscheduling/CircularLookSchedulingTest.java) - * [CircularScanSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/diskscheduling/CircularScanSchedulingTest.java) - * [LookSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/diskscheduling/LookSchedulingTest.java) - * [ScanSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/diskscheduling/ScanSchedulingTest.java) - * [SSFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/diskscheduling/SSFSchedulingTest.java) - * [EDFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/EDFSchedulingTest.java) - * [FairShareSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/FairShareSchedulingTest.java) - * [FCFSSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/FCFSSchedulingTest.java) - * [GangSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/GangSchedulingTest.java) - * [HighestResponseRatioNextSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/HighestResponseRatioNextSchedulingTest.java) - * [JobSchedulingWithDeadlineTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/JobSchedulingWithDeadlineTest.java) - * [LotterySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/LotterySchedulingTest.java) - * [MLFQSchedulerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/MLFQSchedulerTest.java) - * [MultiAgentSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/MultiAgentSchedulingTest.java) - * [NonPreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/NonPreemptivePrioritySchedulingTest.java) - * [PreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java) - * [ProportionalFairSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/ProportionalFairSchedulingTest.java) - * [RandomSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/RandomSchedulingTest.java) - * [RRSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java) - * [SelfAdjustingSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SelfAdjustingSchedulingTest.java) - * [SJFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java) - * [SlackTimeSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SlackTimeSchedulingTest.java) - * [SRTFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java) - * searches - * [BinarySearch2dArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java) - * [BinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BinarySearchTest.java) - * [BM25InvertedIndexTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BM25InvertedIndexTest.java) - * [BreadthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java) - * [DepthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java) - * [ExponentialSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java) - * [FibonacciSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java) - * [HowManyTimesRotatedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java) - * [InterpolationSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/InterpolationSearchTest.java) - * [IterativeBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/IterativeBinarySearchTest.java) - * [IterativeTernarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/IterativeTernarySearchTest.java) - * [JumpSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/JumpSearchTest.java) - * [KMPSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/KMPSearchTest.java) - * [LinearSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/LinearSearchTest.java) - * [LinearSearchThreadTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/LinearSearchThreadTest.java) - * [LowerBoundTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/LowerBoundTest.java) - * [MonteCarloTreeSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/MonteCarloTreeSearchTest.java) - * [OrderAgnosticBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java) - * [PerfectBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java) - * [QuickSelectTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/QuickSelectTest.java) - * [RabinKarpAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java) - * [RandomSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RandomSearchTest.java) - * [RecursiveBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java) - * [RowColumnWiseSorted2dArrayBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java) - * [SaddlebackSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/SaddlebackSearchTest.java) - * [SearchInARowAndColWiseSortedMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrixTest.java) - * [SortOrderAgnosticBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/SortOrderAgnosticBinarySearchTest.java) - * [SquareRootBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/SquareRootBinarySearchTest.java) - * [TernarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/TernarySearchTest.java) - * [TestSearchInARowAndColWiseSortedMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java) - * [UnionFindTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/UnionFindTest.java) - * [UpperBoundTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/UpperBoundTest.java) - * slidingwindow - * [LongestSubarrayWithSumLessOrEqualToKTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/LongestSubarrayWithSumLessOrEqualToKTest.java) - * [LongestSubstringWithoutRepeatingCharactersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharactersTest.java) - * [MaxSumKSizeSubarrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarrayTest.java) - * [MinSumKSizeSubarrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarrayTest.java) - * [ShortestCoprimeSegmentTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegmentTest.java) - * sorts - * [AdaptiveMergeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/AdaptiveMergeSortTest.java) - * [BeadSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BeadSortTest.java) - * [BinaryInsertionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java) - * [BitonicSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BitonicSortTest.java) - * [BogoSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BogoSortTest.java) - * [BubbleSortRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BubbleSortRecursiveTest.java) - * [BubbleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BubbleSortTest.java) - * [BucketSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BucketSortTest.java) - * [CircleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CircleSortTest.java) - * [CocktailShakerSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.java) - * [CombSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CombSortTest.java) - * [CountingSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CountingSortTest.java) - * [CycleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CycleSortTest.java) - * [DarkSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DarkSortTest.java) - * [DualPivotQuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java) - * [DutchNationalFlagSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java) - * [ExchangeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java) - * [FlashSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/FlashSortTest.java) - * [GnomeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/GnomeSortTest.java) - * [HeapSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/HeapSortTest.java) - * [InsertionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java) - * [IntrospectiveSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/IntrospectiveSortTest.java) - * [MergeSortNoExtraSpaceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/MergeSortNoExtraSpaceTest.java) - * [MergeSortRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/MergeSortRecursiveTest.java) - * [MergeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/MergeSortTest.java) - * [OddEvenSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/OddEvenSortTest.java) - * [PancakeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java) - * [PatienceSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/PatienceSortTest.java) - * [PigeonholeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/PigeonholeSortTest.java) - * [QuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/QuickSortTest.java) - * [RadixSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/RadixSortTest.java) - * [SelectionSortRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SelectionSortRecursiveTest.java) - * [SelectionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SelectionSortTest.java) - * [ShellSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/ShellSortTest.java) - * [SimpleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SimpleSortTest.java) - * [SlowSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SlowSortTest.java) - * [SortingAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java) - * [SortUtilsRandomGeneratorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortUtilsRandomGeneratorTest.java) - * [SortUtilsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortUtilsTest.java) - * [SpreadSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SpreadSortTest.java) - * [StalinSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/StalinSortTest.java) - * [StoogeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/StoogeSortTest.java) - * [StrandSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/StrandSortTest.java) - * [SwapSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SwapSortTest.java) - * [TimSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TimSortTest.java) - * [TopologicalSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java) - * [TreeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TreeSortTest.java) - * [WaveSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/WaveSortTest.java) - * [WiggleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java) - * stacks - * [BalancedBracketsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/BalancedBracketsTest.java) - * [CelebrityFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java) - * [DecimalToAnyUsingStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/DecimalToAnyUsingStackTest.java) - * [DuplicateBracketsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/DuplicateBracketsTest.java) - * [GreatestElementConstantTimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/GreatestElementConstantTimeTest.java) - * [InfixToPostfixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java) - * [InfixToPrefixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/InfixToPrefixTest.java) - * [LargestRectangleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/LargestRectangleTest.java) - * [MinStackUsingSingleStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/MinStackUsingSingleStackTest.java) - * [MinStackUsingTwoStacksTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/MinStackUsingTwoStacksTest.java) - * [NextGreaterElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/NextGreaterElementTest.java) - * [NextSmallerElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/NextSmallerElementTest.java) - * [PalindromeWithStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PalindromeWithStackTest.java) - * [PostfixEvaluatorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PostfixEvaluatorTest.java) - * [PostfixToInfixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PostfixToInfixTest.java) - * [PrefixEvaluatorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PrefixEvaluatorTest.java) - * [PrefixToInfixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java) - * [SmallestElementConstantTimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/SmallestElementConstantTimeTest.java) - * [SortStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/SortStackTest.java) - * [StackPostfixNotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java) - * [StackUsingTwoQueuesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/StackUsingTwoQueuesTest.java) - * strings - * [AhoCorasickTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AhoCorasickTest.java) - * [AlphabeticalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java) - * [AnagramsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AnagramsTest.java) - * [CharacterSameTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CharacterSameTest.java) - * [CharactersSameTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CharactersSameTest.java) - * [CheckAnagramsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CheckAnagramsTest.java) - * [CheckVowelsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CheckVowelsTest.java) - * [CountCharTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CountCharTest.java) - * [CountWordsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CountWordsTest.java) - * [HammingDistanceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/HammingDistanceTest.java) - * [HorspoolSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java) - * [IsomorphicTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/IsomorphicTest.java) - * [LetterCombinationsOfPhoneNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumberTest.java) - * [LongestCommonPrefixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/LongestCommonPrefixTest.java) - * [LongestNonRepetitiveSubstringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/LongestNonRepetitiveSubstringTest.java) - * [LongestPalindromicSubstringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/LongestPalindromicSubstringTest.java) - * [LowerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/LowerTest.java) - * [ManacherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/ManacherTest.java) - * [MyAtoiTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/MyAtoiTest.java) - * [PalindromeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/PalindromeTest.java) - * [PangramTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/PangramTest.java) - * [PermuteStringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/PermuteStringTest.java) - * [ReturnSubsequenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/ReturnSubsequenceTest.java) - * [ReverseStringRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/ReverseStringRecursiveTest.java) - * [ReverseStringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/ReverseStringTest.java) - * [ReverseWordsInStringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java) - * [RotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/RotationTest.java) - * [StringCompressionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/StringCompressionTest.java) - * [StringMatchFiniteAutomataTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/StringMatchFiniteAutomataTest.java) - * [UpperTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/UpperTest.java) - * [ValidParenthesesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java) - * [WordLadderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/WordLadderTest.java) - * zigZagPattern - * [ZigZagPatternTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/zigZagPattern/ZigZagPatternTest.java) - * tree - * [HeavyLightDecompositionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/tree/HeavyLightDecompositionTest.java) +- 📁 **main** + - 📁 **java** + - 📁 **com** + - 📁 **thealgorithms** + - 📁 **audiofilters** + - 📄 [EMAFilter](src/main/java/com/thealgorithms/audiofilters/EMAFilter.java) + - 📄 [IIRFilter](src/main/java/com/thealgorithms/audiofilters/IIRFilter.java) + - 📁 **backtracking** + - 📄 [AllPathsFromSourceToTarget](src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java) + - 📄 [ArrayCombination](src/main/java/com/thealgorithms/backtracking/ArrayCombination.java) + - 📄 [Combination](src/main/java/com/thealgorithms/backtracking/Combination.java) + - 📄 [CrosswordSolver](src/main/java/com/thealgorithms/backtracking/CrosswordSolver.java) + - 📄 [FloodFill](src/main/java/com/thealgorithms/backtracking/FloodFill.java) + - 📄 [KnightsTour](src/main/java/com/thealgorithms/backtracking/KnightsTour.java) + - 📄 [MColoring](src/main/java/com/thealgorithms/backtracking/MColoring.java) + - 📄 [MazeRecursion](src/main/java/com/thealgorithms/backtracking/MazeRecursion.java) + - 📄 [NQueens](src/main/java/com/thealgorithms/backtracking/NQueens.java) + - 📄 [ParenthesesGenerator](src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java) + - 📄 [Permutation](src/main/java/com/thealgorithms/backtracking/Permutation.java) + - 📄 [PowerSum](src/main/java/com/thealgorithms/backtracking/PowerSum.java) + - 📄 [SubsequenceFinder](src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java) + - 📄 [WordPatternMatcher](src/main/java/com/thealgorithms/backtracking/WordPatternMatcher.java) + - 📄 [WordSearch](src/main/java/com/thealgorithms/backtracking/WordSearch.java) + - 📁 **bitmanipulation** + - 📄 [BcdConversion](src/main/java/com/thealgorithms/bitmanipulation/BcdConversion.java) + - 📄 [BinaryPalindromeCheck](src/main/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheck.java) + - 📄 [BitSwap](src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java) + - 📄 [BooleanAlgebraGates](src/main/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGates.java) + - 📄 [ClearLeftmostSetBit](src/main/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBit.java) + - 📄 [CountLeadingZeros](src/main/java/com/thealgorithms/bitmanipulation/CountLeadingZeros.java) + - 📄 [CountSetBits](src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java) + - 📄 [FindNthBit](src/main/java/com/thealgorithms/bitmanipulation/FindNthBit.java) + - 📄 [FirstDifferentBit](src/main/java/com/thealgorithms/bitmanipulation/FirstDifferentBit.java) + - 📄 [GenerateSubsets](src/main/java/com/thealgorithms/bitmanipulation/GenerateSubsets.java) + - 📄 [GrayCodeConversion](src/main/java/com/thealgorithms/bitmanipulation/GrayCodeConversion.java) + - 📄 [HammingDistance](src/main/java/com/thealgorithms/bitmanipulation/HammingDistance.java) + - 📄 [HigherLowerPowerOfTwo](src/main/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwo.java) + - 📄 [HighestSetBit](src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java) + - 📄 [IndexOfRightMostSetBit](src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java) + - 📄 [IsEven](src/main/java/com/thealgorithms/bitmanipulation/IsEven.java) + - 📄 [IsPowerTwo](src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java) + - 📄 [LowestSetBit](src/main/java/com/thealgorithms/bitmanipulation/LowestSetBit.java) + - 📄 [ModuloPowerOfTwo](src/main/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwo.java) + - 📄 [NextHigherSameBitCount](src/main/java/com/thealgorithms/bitmanipulation/NextHigherSameBitCount.java) + - 📄 [NonRepeatingNumberFinder](src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java) + - 📄 [NumberAppearingOddTimes](src/main/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimes.java) + - 📄 [NumbersDifferentSigns](src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java) + - 📄 [OneBitDifference](src/main/java/com/thealgorithms/bitmanipulation/OneBitDifference.java) + - 📄 [OnesComplement](src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java) + - 📄 [ParityCheck](src/main/java/com/thealgorithms/bitmanipulation/ParityCheck.java) + - 📄 [ReverseBits](src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java) + - 📄 [SingleBitOperations](src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java) + - 📄 [SingleElement](src/main/java/com/thealgorithms/bitmanipulation/SingleElement.java) + - 📄 [SwapAdjacentBits](src/main/java/com/thealgorithms/bitmanipulation/SwapAdjacentBits.java) + - 📄 [TwosComplement](src/main/java/com/thealgorithms/bitmanipulation/TwosComplement.java) + - 📄 [Xs3Conversion](src/main/java/com/thealgorithms/bitmanipulation/Xs3Conversion.java) + - 📁 **ciphers** + - 📄 [ADFGVXCipher](src/main/java/com/thealgorithms/ciphers/ADFGVXCipher.java) + - 📄 [AES](src/main/java/com/thealgorithms/ciphers/AES.java) + - 📄 [AESEncryption](src/main/java/com/thealgorithms/ciphers/AESEncryption.java) + - 📄 [AffineCipher](src/main/java/com/thealgorithms/ciphers/AffineCipher.java) + - 📄 [AtbashCipher](src/main/java/com/thealgorithms/ciphers/AtbashCipher.java) + - 📄 [Autokey](src/main/java/com/thealgorithms/ciphers/Autokey.java) + - 📄 [BaconianCipher](src/main/java/com/thealgorithms/ciphers/BaconianCipher.java) + - 📄 [Blowfish](src/main/java/com/thealgorithms/ciphers/Blowfish.java) + - 📄 [Caesar](src/main/java/com/thealgorithms/ciphers/Caesar.java) + - 📄 [ColumnarTranspositionCipher](src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java) + - 📄 [DES](src/main/java/com/thealgorithms/ciphers/DES.java) + - 📄 [DiffieHellman](src/main/java/com/thealgorithms/ciphers/DiffieHellman.java) + - 📄 [ECC](src/main/java/com/thealgorithms/ciphers/ECC.java) + - 📄 [HillCipher](src/main/java/com/thealgorithms/ciphers/HillCipher.java) + - 📄 [MonoAlphabetic](src/main/java/com/thealgorithms/ciphers/MonoAlphabetic.java) + - 📄 [PlayfairCipher](src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java) + - 📄 [Polybius](src/main/java/com/thealgorithms/ciphers/Polybius.java) + - 📄 [ProductCipher](src/main/java/com/thealgorithms/ciphers/ProductCipher.java) + - 📄 [RSA](src/main/java/com/thealgorithms/ciphers/RSA.java) + - 📄 [RailFenceCipher](src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java) + - 📄 [SimpleSubCipher](src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java) + - 📄 [Vigenere](src/main/java/com/thealgorithms/ciphers/Vigenere.java) + - 📄 [XORCipher](src/main/java/com/thealgorithms/ciphers/XORCipher.java) + - 📁 **a5** + - 📄 [A5Cipher](src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java) + - 📄 [A5KeyStreamGenerator](src/main/java/com/thealgorithms/ciphers/a5/A5KeyStreamGenerator.java) + - 📄 [BaseLFSR](src/main/java/com/thealgorithms/ciphers/a5/BaseLFSR.java) + - 📄 [CompositeLFSR](src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java) + - 📄 [LFSR](src/main/java/com/thealgorithms/ciphers/a5/LFSR.java) + - 📄 [Utils](src/main/java/com/thealgorithms/ciphers/a5/Utils.java) + - 📁 **conversions** + - 📄 [AffineConverter](src/main/java/com/thealgorithms/conversions/AffineConverter.java) + - 📄 [AnyBaseToAnyBase](src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java) + - 📄 [AnyBaseToDecimal](src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java) + - 📄 [AnytoAny](src/main/java/com/thealgorithms/conversions/AnytoAny.java) + - 📄 [BinaryToDecimal](src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java) + - 📄 [BinaryToHexadecimal](src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java) + - 📄 [BinaryToOctal](src/main/java/com/thealgorithms/conversions/BinaryToOctal.java) + - 📄 [DecimalToAnyBase](src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java) + - 📄 [DecimalToBinary](src/main/java/com/thealgorithms/conversions/DecimalToBinary.java) + - 📄 [DecimalToHexadecimal](src/main/java/com/thealgorithms/conversions/DecimalToHexadecimal.java) + - 📄 [DecimalToOctal](src/main/java/com/thealgorithms/conversions/DecimalToOctal.java) + - 📄 [EndianConverter](src/main/java/com/thealgorithms/conversions/EndianConverter.java) + - 📄 [HexToOct](src/main/java/com/thealgorithms/conversions/HexToOct.java) + - 📄 [HexaDecimalToBinary](src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java) + - 📄 [HexaDecimalToDecimal](src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java) + - 📄 [IPConverter](src/main/java/com/thealgorithms/conversions/IPConverter.java) + - 📄 [IPv6Converter](src/main/java/com/thealgorithms/conversions/IPv6Converter.java) + - 📄 [IntegerToEnglish](src/main/java/com/thealgorithms/conversions/IntegerToEnglish.java) + - 📄 [IntegerToRoman](src/main/java/com/thealgorithms/conversions/IntegerToRoman.java) + - 📄 [MorseCodeConverter](src/main/java/com/thealgorithms/conversions/MorseCodeConverter.java) + - 📄 [NumberToWords](src/main/java/com/thealgorithms/conversions/NumberToWords.java) + - 📄 [OctalToBinary](src/main/java/com/thealgorithms/conversions/OctalToBinary.java) + - 📄 [OctalToDecimal](src/main/java/com/thealgorithms/conversions/OctalToDecimal.java) + - 📄 [OctalToHexadecimal](src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java) + - 📄 [PhoneticAlphabetConverter](src/main/java/com/thealgorithms/conversions/PhoneticAlphabetConverter.java) + - 📄 [RgbHsvConversion](src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java) + - 📄 [RomanToInteger](src/main/java/com/thealgorithms/conversions/RomanToInteger.java) + - 📄 [TurkishToLatinConversion](src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java) + - 📄 [UnitConversions](src/main/java/com/thealgorithms/conversions/UnitConversions.java) + - 📄 [UnitsConverter](src/main/java/com/thealgorithms/conversions/UnitsConverter.java) + - 📄 [WordsToNumber](src/main/java/com/thealgorithms/conversions/WordsToNumber.java) + - 📁 **datastructures** + - 📄 [Node](src/main/java/com/thealgorithms/datastructures/Node.java) + - 📁 **bags** + - 📄 [Bag](src/main/java/com/thealgorithms/datastructures/bags/Bag.java) + - 📁 **bloomfilter** + - 📄 [BloomFilter](src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java) + - 📁 **buffers** + - 📄 [CircularBuffer](src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java) + - 📁 **caches** + - 📄 [LFUCache](src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java) + - 📄 [LRUCache](src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java) + - 📄 [MRUCache](src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java) + - 📁 **crdt** + - 📄 [GCounter](src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java) + - 📄 [GSet](src/main/java/com/thealgorithms/datastructures/crdt/GSet.java) + - 📄 [LWWElementSet](src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java) + - 📄 [ORSet](src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java) + - 📄 [PNCounter](src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java) + - 📄 [TwoPSet](src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java) + - 📁 **disjointsetunion** + - 📄 [DisjointSetUnion](src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java) + - 📄 [Node](src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java) + - 📁 **dynamicarray** + - 📄 [DynamicArray](src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java) + - 📁 **graphs** + - 📄 [AStar](src/main/java/com/thealgorithms/datastructures/graphs/AStar.java) + - 📄 [BellmanFord](src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java) + - 📄 [BipartiteGraphDFS](src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFS.java) + - 📄 [BoruvkaAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java) + - 📄 [ConnectedComponent](src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java) + - 📄 [Cycles](src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java) + - 📄 [DijkstraAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithm.java) + - 📄 [DijkstraOptimizedAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithm.java) + - 📄 [EdmondsBlossomAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithm.java) + - 📄 [FloydWarshall](src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java) + - 📄 [FordFulkerson](src/main/java/com/thealgorithms/datastructures/graphs/FordFulkerson.java) + - 📄 [Graphs](src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java) + - 📄 [HamiltonianCycle](src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java) + - 📄 [JohnsonsAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/JohnsonsAlgorithm.java) + - 📄 [KahnsAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java) + - 📄 [Kosaraju](src/main/java/com/thealgorithms/datastructures/graphs/Kosaraju.java) + - 📄 [Kruskal](src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java) + - 📄 [MatrixGraphs](src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java) + - 📄 [PrimMST](src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java) + - 📄 [README](src/main/java/com/thealgorithms/datastructures/graphs/README.md) + - 📄 [TarjansAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java) + - 📄 [UndirectedAdjacencyListGraph](src/main/java/com/thealgorithms/datastructures/graphs/UndirectedAdjacencyListGraph.java) + - 📄 [WelshPowell](src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java) + - 📁 **hashmap** + - 📄 [Readme](src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md) + - 📁 **hashing** + - 📄 [GenericHashMapUsingArray](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java) + - 📄 [GenericHashMapUsingArrayList](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayList.java) + - 📄 [HashMap](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java) + - 📄 [HashMapCuckooHashing](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java) + - 📄 [Intersection](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection.java) + - 📄 [LinearProbingHashMap](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java) + - 📄 [MainCuckooHashing](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainCuckooHashing.java) + - 📄 [MajorityElement](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElement.java) + - 📄 [Map](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Map.java) + - 📁 **heaps** + - 📄 [EmptyHeapException](src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java) + - 📄 [FibonacciHeap](src/main/java/com/thealgorithms/datastructures/heaps/FibonacciHeap.java) + - 📄 [GenericHeap](src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java) + - 📄 [Heap](src/main/java/com/thealgorithms/datastructures/heaps/Heap.java) + - 📄 [HeapElement](src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java) + - 📄 [KthElementFinder](src/main/java/com/thealgorithms/datastructures/heaps/KthElementFinder.java) + - 📄 [LeftistHeap](src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java) + - 📄 [MaxHeap](src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java) + - 📄 [MedianFinder](src/main/java/com/thealgorithms/datastructures/heaps/MedianFinder.java) + - 📄 [MergeKSortedArrays](src/main/java/com/thealgorithms/datastructures/heaps/MergeKSortedArrays.java) + - 📄 [MinHeap](src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java) + - 📄 [MinPriorityQueue](src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java) + - 📄 [Readme](src/main/java/com/thealgorithms/datastructures/heaps/Readme.md) + - 📁 **lists** + - 📄 [CircleLinkedList](src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java) + - 📄 [CountSinglyLinkedListRecursion](src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java) + - 📄 [CreateAndDetectLoop](src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java) + - 📄 [CursorLinkedList](src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java) + - 📄 [DoublyLinkedList](src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java) + - 📄 [MergeKSortedLinkedList](src/main/java/com/thealgorithms/datastructures/lists/MergeKSortedLinkedList.java) + - 📄 [MergeSortedArrayList](src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java) + - 📄 [MergeSortedSinglyLinkedList](src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java) + - 📄 [QuickSortLinkedList](src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java) + - 📄 [README](src/main/java/com/thealgorithms/datastructures/lists/README.md) + - 📄 [RandomNode](src/main/java/com/thealgorithms/datastructures/lists/RandomNode.java) + - 📄 [ReverseKGroup](src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java) + - 📄 [RotateSinglyLinkedLists](src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java) + - 📄 [SearchSinglyLinkedListRecursion](src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java) + - 📄 [SinglyLinkedList](src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java) + - 📄 [SinglyLinkedListNode](src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedListNode.java) + - 📄 [SkipList](src/main/java/com/thealgorithms/datastructures/lists/SkipList.java) + - 📄 [SortedLinkedList](src/main/java/com/thealgorithms/datastructures/lists/SortedLinkedList.java) + - 📁 **queues** + - 📄 [CircularQueue](src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java) + - 📄 [Deque](src/main/java/com/thealgorithms/datastructures/queues/Deque.java) + - 📄 [GenericArrayListQueue](src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java) + - 📄 [LinkedQueue](src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java) + - 📄 [PriorityQueues](src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java) + - 📄 [Queue](src/main/java/com/thealgorithms/datastructures/queues/Queue.java) + - 📄 [QueueByTwoStacks](src/main/java/com/thealgorithms/datastructures/queues/QueueByTwoStacks.java) + - 📄 [README](src/main/java/com/thealgorithms/datastructures/queues/README.md) + - 📄 [SlidingWindowMaximum](src/main/java/com/thealgorithms/datastructures/queues/SlidingWindowMaximum.java) + - 📄 [TokenBucket](src/main/java/com/thealgorithms/datastructures/queues/TokenBucket.java) + - 📁 **stacks** + - 📄 [NodeStack](src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java) + - 📄 [README](src/main/java/com/thealgorithms/datastructures/stacks/README.md) + - 📄 [ReverseStack](src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java) + - 📄 [Stack](src/main/java/com/thealgorithms/datastructures/stacks/Stack.java) + - 📄 [StackArray](src/main/java/com/thealgorithms/datastructures/stacks/StackArray.java) + - 📄 [StackArrayList](src/main/java/com/thealgorithms/datastructures/stacks/StackArrayList.java) + - 📄 [StackOfLinkedList](src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java) + - 📁 **trees** + - 📄 [AVLSimple](src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java) + - 📄 [AVLTree](src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java) + - 📄 [BSTFromSortedArray](src/main/java/com/thealgorithms/datastructures/trees/BSTFromSortedArray.java) + - 📄 [BSTIterative](src/main/java/com/thealgorithms/datastructures/trees/BSTIterative.java) + - 📄 [BSTRecursive](src/main/java/com/thealgorithms/datastructures/trees/BSTRecursive.java) + - 📄 [BSTRecursiveGeneric](src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java) + - 📄 [BTree](src/main/java/com/thealgorithms/datastructures/trees/BTree.java) + - 📄 [BinaryTree](src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java) + - 📄 [BoundaryTraversal](src/main/java/com/thealgorithms/datastructures/trees/BoundaryTraversal.java) + - 📄 [CeilInBinarySearchTree](src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java) + - 📄 [CheckBinaryTreeIsValidBST](src/main/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBST.java) + - 📄 [CheckIfBinaryTreeBalanced](src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java) + - 📄 [CheckTreeIsSymmetric](src/main/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetric.java) + - 📄 [CreateBinaryTreeFromInorderPreorder](src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java) + - 📄 [FenwickTree](src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java) + - 📄 [GenericTree](src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java) + - 📄 [InorderTraversal](src/main/java/com/thealgorithms/datastructures/trees/InorderTraversal.java) + - 📄 [KDTree](src/main/java/com/thealgorithms/datastructures/trees/KDTree.java) + - 📄 [LCA](src/main/java/com/thealgorithms/datastructures/trees/LCA.java) + - 📄 [LazySegmentTree](src/main/java/com/thealgorithms/datastructures/trees/LazySegmentTree.java) + - 📄 [LevelOrderTraversal](src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java) + - 📄 [PostOrderTraversal](src/main/java/com/thealgorithms/datastructures/trees/PostOrderTraversal.java) + - 📄 [PreOrderTraversal](src/main/java/com/thealgorithms/datastructures/trees/PreOrderTraversal.java) + - 📄 [PrintTopViewofTree](src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java) + - 📄 [QuadTree](src/main/java/com/thealgorithms/datastructures/trees/QuadTree.java) + - 📄 [README](src/main/java/com/thealgorithms/datastructures/trees/README.md) + - 📄 [RedBlackBST](src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java) + - 📄 [SameTreesCheck](src/main/java/com/thealgorithms/datastructures/trees/SameTreesCheck.java) + - 📄 [SegmentTree](src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java) + - 📄 [SplayTree](src/main/java/com/thealgorithms/datastructures/trees/SplayTree.java) + - 📄 [Treap](src/main/java/com/thealgorithms/datastructures/trees/Treap.java) + - 📄 [TreeRandomNode](src/main/java/com/thealgorithms/datastructures/trees/TreeRandomNode.java) + - 📄 [Trie](src/main/java/com/thealgorithms/datastructures/trees/Trie.java) + - 📄 [VerticalOrderTraversal](src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java) + - 📄 [ZigzagTraversal](src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java) + - 📄 [nearestRightKey](src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java) + - 📁 **devutils** + - 📁 **entities** + - 📄 [ProcessDetails](src/main/java/com/thealgorithms/devutils/entities/ProcessDetails.java) + - 📁 **nodes** + - 📄 [LargeTreeNode](src/main/java/com/thealgorithms/devutils/nodes/LargeTreeNode.java) + - 📄 [Node](src/main/java/com/thealgorithms/devutils/nodes/Node.java) + - 📄 [SimpleNode](src/main/java/com/thealgorithms/devutils/nodes/SimpleNode.java) + - 📄 [SimpleTreeNode](src/main/java/com/thealgorithms/devutils/nodes/SimpleTreeNode.java) + - 📄 [TreeNode](src/main/java/com/thealgorithms/devutils/nodes/TreeNode.java) + - 📁 **searches** + - 📄 [MatrixSearchAlgorithm](src/main/java/com/thealgorithms/devutils/searches/MatrixSearchAlgorithm.java) + - 📄 [SearchAlgorithm](src/main/java/com/thealgorithms/devutils/searches/SearchAlgorithm.java) + - 📁 **divideandconquer** + - 📄 [BinaryExponentiation](src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java) + - 📄 [ClosestPair](src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java) + - 📄 [CountingInversions](src/main/java/com/thealgorithms/divideandconquer/CountingInversions.java) + - 📄 [MedianOfTwoSortedArrays](src/main/java/com/thealgorithms/divideandconquer/MedianOfTwoSortedArrays.java) + - 📄 [SkylineAlgorithm](src/main/java/com/thealgorithms/divideandconquer/SkylineAlgorithm.java) + - 📄 [StrassenMatrixMultiplication](src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java) + - 📄 [TilingProblem](src/main/java/com/thealgorithms/divideandconquer/TilingProblem.java) + - 📁 **dynamicprogramming** + - 📄 [Abbreviation](src/main/java/com/thealgorithms/dynamicprogramming/Abbreviation.java) + - 📄 [AllConstruct](src/main/java/com/thealgorithms/dynamicprogramming/AllConstruct.java) + - 📄 [AssignmentUsingBitmask](src/main/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmask.java) + - 📄 [BoardPath](src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java) + - 📄 [BoundaryFill](src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java) + - 📄 [BruteForceKnapsack](src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java) + - 📄 [CatalanNumber](src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java) + - 📄 [ClimbingStairs](src/main/java/com/thealgorithms/dynamicprogramming/ClimbingStairs.java) + - 📄 [CoinChange](src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java) + - 📄 [CountFriendsPairing](src/main/java/com/thealgorithms/dynamicprogramming/CountFriendsPairing.java) + - 📄 [DiceThrow](src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java) + - 📄 [EditDistance](src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java) + - 📄 [EggDropping](src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java) + - 📄 [Fibonacci](src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java) + - 📄 [KadaneAlgorithm](src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java) + - 📄 [Knapsack](src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java) + - 📄 [KnapsackMemoization](src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java) + - 📄 [LevenshteinDistance](src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java) + - 📄 [LongestAlternatingSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java) + - 📄 [LongestArithmeticSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequence.java) + - 📄 [LongestCommonSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java) + - 📄 [LongestIncreasingSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java) + - 📄 [LongestIncreasingSubsequenceNLogN](src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogN.java) + - 📄 [LongestPalindromicSubsequence](src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java) + - 📄 [LongestPalindromicSubstring](src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java) + - 📄 [LongestValidParentheses](src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java) + - 📄 [MatrixChainMultiplication](src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java) + - 📄 [MatrixChainRecursiveTopDownMemoisation](src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java) + - 📄 [MaximumSumOfNonAdjacentElements](src/main/java/com/thealgorithms/dynamicprogramming/MaximumSumOfNonAdjacentElements.java) + - 📄 [MinimumPathSum](src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java) + - 📄 [MinimumSumPartition](src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java) + - 📄 [NewManShanksPrime](src/main/java/com/thealgorithms/dynamicprogramming/NewManShanksPrime.java) + - 📄 [OptimalJobScheduling](src/main/java/com/thealgorithms/dynamicprogramming/OptimalJobScheduling.java) + - 📄 [PalindromicPartitioning](src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java) + - 📄 [PartitionProblem](src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java) + - 📄 [RegexMatching](src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java) + - 📄 [RodCutting](src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java) + - 📄 [ShortestCommonSupersequenceLength](src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java) + - 📄 [SubsetCount](src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java) + - 📄 [SubsetSum](src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java) + - 📄 [SubsetSumSpaceOptimized](src/main/java/com/thealgorithms/dynamicprogramming/SubsetSumSpaceOptimized.java) + - 📄 [SumOfSubset](src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java) + - 📄 [TreeMatching](src/main/java/com/thealgorithms/dynamicprogramming/TreeMatching.java) + - 📄 [Tribonacci](src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java) + - 📄 [UniquePaths](src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java) + - 📄 [UniqueSubsequencesCount](src/main/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCount.java) + - 📄 [WildcardMatching](src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java) + - 📄 [WineProblem](src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java) + - 📁 **geometry** + - 📄 [BresenhamLine](src/main/java/com/thealgorithms/geometry/BresenhamLine.java) + - 📄 [ConvexHull](src/main/java/com/thealgorithms/geometry/ConvexHull.java) + - 📄 [GrahamScan](src/main/java/com/thealgorithms/geometry/GrahamScan.java) + - 📄 [MidpointCircle](src/main/java/com/thealgorithms/geometry/MidpointCircle.java) + - 📄 [MidpointEllipse](src/main/java/com/thealgorithms/geometry/MidpointEllipse.java) + - 📄 [Point](src/main/java/com/thealgorithms/geometry/Point.java) + - 📁 **graph** + - 📄 [ConstrainedShortestPath](src/main/java/com/thealgorithms/graph/ConstrainedShortestPath.java) + - 📄 [StronglyConnectedComponentOptimized](src/main/java/com/thealgorithms/graph/StronglyConnectedComponentOptimized.java) + - 📄 [TravelingSalesman](src/main/java/com/thealgorithms/graph/TravelingSalesman.java) + - 📁 **greedyalgorithms** + - 📄 [ActivitySelection](src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java) + - 📄 [BandwidthAllocation](src/main/java/com/thealgorithms/greedyalgorithms/BandwidthAllocation.java) + - 📄 [BinaryAddition](src/main/java/com/thealgorithms/greedyalgorithms/BinaryAddition.java) + - 📄 [CoinChange](src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java) + - 📄 [DigitSeparation](src/main/java/com/thealgorithms/greedyalgorithms/DigitSeparation.java) + - 📄 [EgyptianFraction](src/main/java/com/thealgorithms/greedyalgorithms/EgyptianFraction.java) + - 📄 [FractionalKnapsack](src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java) + - 📄 [GaleShapley](src/main/java/com/thealgorithms/greedyalgorithms/GaleShapley.java) + - 📄 [JobSequencing](src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java) + - 📄 [KCenters](src/main/java/com/thealgorithms/greedyalgorithms/KCenters.java) + - 📄 [MergeIntervals](src/main/java/com/thealgorithms/greedyalgorithms/MergeIntervals.java) + - 📄 [MinimizingLateness](src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java) + - 📄 [MinimumWaitingTime](src/main/java/com/thealgorithms/greedyalgorithms/MinimumWaitingTime.java) + - 📄 [OptimalFileMerging](src/main/java/com/thealgorithms/greedyalgorithms/OptimalFileMerging.java) + - 📄 [StockProfitCalculator](src/main/java/com/thealgorithms/greedyalgorithms/StockProfitCalculator.java) + - 📁 **io** + - 📄 [BufferedReader](src/main/java/com/thealgorithms/io/BufferedReader.java) + - 📁 **lineclipping** + - 📄 [CohenSutherland](src/main/java/com/thealgorithms/lineclipping/CohenSutherland.java) + - 📄 [LiangBarsky](src/main/java/com/thealgorithms/lineclipping/LiangBarsky.java) + - 📁 **utils** + - 📄 [Line](src/main/java/com/thealgorithms/lineclipping/utils/Line.java) + - 📄 [Point](src/main/java/com/thealgorithms/lineclipping/utils/Point.java) + - 📁 **maths** + - 📄 [ADTFraction](src/main/java/com/thealgorithms/maths/ADTFraction.java) + - 📄 [AbsoluteMax](src/main/java/com/thealgorithms/maths/AbsoluteMax.java) + - 📄 [AbsoluteMin](src/main/java/com/thealgorithms/maths/AbsoluteMin.java) + - 📄 [AbsoluteValue](src/main/java/com/thealgorithms/maths/AbsoluteValue.java) + - 📄 [AliquotSum](src/main/java/com/thealgorithms/maths/AliquotSum.java) + - 📄 [AmicableNumber](src/main/java/com/thealgorithms/maths/AmicableNumber.java) + - 📄 [Area](src/main/java/com/thealgorithms/maths/Area.java) + - 📄 [Armstrong](src/main/java/com/thealgorithms/maths/Armstrong.java) + - 📄 [AutoCorrelation](src/main/java/com/thealgorithms/maths/AutoCorrelation.java) + - 📄 [AutomorphicNumber](src/main/java/com/thealgorithms/maths/AutomorphicNumber.java) + - 📄 [Average](src/main/java/com/thealgorithms/maths/Average.java) + - 📄 [BinaryPow](src/main/java/com/thealgorithms/maths/BinaryPow.java) + - 📄 [BinomialCoefficient](src/main/java/com/thealgorithms/maths/BinomialCoefficient.java) + - 📄 [CatalanNumbers](src/main/java/com/thealgorithms/maths/CatalanNumbers.java) + - 📄 [Ceil](src/main/java/com/thealgorithms/maths/Ceil.java) + - 📄 [ChineseRemainderTheorem](src/main/java/com/thealgorithms/maths/ChineseRemainderTheorem.java) + - 📄 [CircularConvolutionFFT](src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java) + - 📄 [CollatzConjecture](src/main/java/com/thealgorithms/maths/CollatzConjecture.java) + - 📄 [Combinations](src/main/java/com/thealgorithms/maths/Combinations.java) + - 📄 [Convolution](src/main/java/com/thealgorithms/maths/Convolution.java) + - 📄 [ConvolutionFFT](src/main/java/com/thealgorithms/maths/ConvolutionFFT.java) + - 📄 [CrossCorrelation](src/main/java/com/thealgorithms/maths/CrossCorrelation.java) + - 📄 [DeterminantOfMatrix](src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java) + - 📄 [DigitalRoot](src/main/java/com/thealgorithms/maths/DigitalRoot.java) + - 📄 [DistanceFormula](src/main/java/com/thealgorithms/maths/DistanceFormula.java) + - 📄 [DudeneyNumber](src/main/java/com/thealgorithms/maths/DudeneyNumber.java) + - 📄 [EulerMethod](src/main/java/com/thealgorithms/maths/EulerMethod.java) + - 📄 [EulersFunction](src/main/java/com/thealgorithms/maths/EulersFunction.java) + - 📄 [FFT](src/main/java/com/thealgorithms/maths/FFT.java) + - 📄 [FFTBluestein](src/main/java/com/thealgorithms/maths/FFTBluestein.java) + - 📄 [Factorial](src/main/java/com/thealgorithms/maths/Factorial.java) + - 📄 [FactorialRecursion](src/main/java/com/thealgorithms/maths/FactorialRecursion.java) + - 📄 [FastExponentiation](src/main/java/com/thealgorithms/maths/FastExponentiation.java) + - 📄 [FastInverseSqrt](src/main/java/com/thealgorithms/maths/FastInverseSqrt.java) + - 📄 [FibonacciJavaStreams](src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java) + - 📄 [FibonacciLoop](src/main/java/com/thealgorithms/maths/FibonacciLoop.java) + - 📄 [FibonacciNumberCheck](src/main/java/com/thealgorithms/maths/FibonacciNumberCheck.java) + - 📄 [FibonacciNumberGoldenRation](src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java) + - 📄 [FindKthNumber](src/main/java/com/thealgorithms/maths/FindKthNumber.java) + - 📄 [FindMax](src/main/java/com/thealgorithms/maths/FindMax.java) + - 📄 [FindMaxRecursion](src/main/java/com/thealgorithms/maths/FindMaxRecursion.java) + - 📄 [FindMin](src/main/java/com/thealgorithms/maths/FindMin.java) + - 📄 [FindMinRecursion](src/main/java/com/thealgorithms/maths/FindMinRecursion.java) + - 📄 [Floor](src/main/java/com/thealgorithms/maths/Floor.java) + - 📄 [FrizzyNumber](src/main/java/com/thealgorithms/maths/FrizzyNumber.java) + - 📄 [GCD](src/main/java/com/thealgorithms/maths/GCD.java) + - 📄 [GCDRecursion](src/main/java/com/thealgorithms/maths/GCDRecursion.java) + - 📄 [Gaussian](src/main/java/com/thealgorithms/maths/Gaussian.java) + - 📄 [GenericRoot](src/main/java/com/thealgorithms/maths/GenericRoot.java) + - 📄 [GoldbachConjecture](src/main/java/com/thealgorithms/maths/GoldbachConjecture.java) + - 📄 [HarshadNumber](src/main/java/com/thealgorithms/maths/HarshadNumber.java) + - 📄 [HeronsFormula](src/main/java/com/thealgorithms/maths/HeronsFormula.java) + - 📄 [JosephusProblem](src/main/java/com/thealgorithms/maths/JosephusProblem.java) + - 📄 [JugglerSequence](src/main/java/com/thealgorithms/maths/JugglerSequence.java) + - 📄 [KaprekarNumbers](src/main/java/com/thealgorithms/maths/KaprekarNumbers.java) + - 📄 [KaratsubaMultiplication](src/main/java/com/thealgorithms/maths/KaratsubaMultiplication.java) + - 📄 [KeithNumber](src/main/java/com/thealgorithms/maths/KeithNumber.java) + - 📄 [KrishnamurthyNumber](src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java) + - 📄 [LeastCommonMultiple](src/main/java/com/thealgorithms/maths/LeastCommonMultiple.java) + - 📄 [LeonardoNumber](src/main/java/com/thealgorithms/maths/LeonardoNumber.java) + - 📄 [LinearDiophantineEquationsSolver](src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java) + - 📄 [LongDivision](src/main/java/com/thealgorithms/maths/LongDivision.java) + - 📄 [LucasSeries](src/main/java/com/thealgorithms/maths/LucasSeries.java) + - 📄 [MagicSquare](src/main/java/com/thealgorithms/maths/MagicSquare.java) + - 📄 [MathBuilder](src/main/java/com/thealgorithms/maths/MathBuilder.java) + - 📄 [MaxValue](src/main/java/com/thealgorithms/maths/MaxValue.java) + - 📄 [Means](src/main/java/com/thealgorithms/maths/Means.java) + - 📄 [Median](src/main/java/com/thealgorithms/maths/Median.java) + - 📄 [MinValue](src/main/java/com/thealgorithms/maths/MinValue.java) + - 📄 [Mode](src/main/java/com/thealgorithms/maths/Mode.java) + - 📄 [NonRepeatingElement](src/main/java/com/thealgorithms/maths/NonRepeatingElement.java) + - 📄 [NthUglyNumber](src/main/java/com/thealgorithms/maths/NthUglyNumber.java) + - 📄 [NumberOfDigits](src/main/java/com/thealgorithms/maths/NumberOfDigits.java) + - 📄 [PalindromeNumber](src/main/java/com/thealgorithms/maths/PalindromeNumber.java) + - 📄 [ParseInteger](src/main/java/com/thealgorithms/maths/ParseInteger.java) + - 📄 [PascalTriangle](src/main/java/com/thealgorithms/maths/PascalTriangle.java) + - 📄 [PerfectCube](src/main/java/com/thealgorithms/maths/PerfectCube.java) + - 📄 [PerfectNumber](src/main/java/com/thealgorithms/maths/PerfectNumber.java) + - 📄 [PerfectSquare](src/main/java/com/thealgorithms/maths/PerfectSquare.java) + - 📄 [Perimeter](src/main/java/com/thealgorithms/maths/Perimeter.java) + - 📄 [PiNilakantha](src/main/java/com/thealgorithms/maths/PiNilakantha.java) + - 📄 [PollardRho](src/main/java/com/thealgorithms/maths/PollardRho.java) + - 📄 [Pow](src/main/java/com/thealgorithms/maths/Pow.java) + - 📄 [PowerOfTwoOrNot](src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java) + - 📄 [PowerUsingRecursion](src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java) + - 📁 **Prime** + - 📄 [LiouvilleLambdaFunction](src/main/java/com/thealgorithms/maths/Prime/LiouvilleLambdaFunction.java) + - 📄 [MillerRabinPrimalityCheck](src/main/java/com/thealgorithms/maths/Prime/MillerRabinPrimalityCheck.java) + - 📄 [MobiusFunction](src/main/java/com/thealgorithms/maths/Prime/MobiusFunction.java) + - 📄 [PrimeCheck](src/main/java/com/thealgorithms/maths/Prime/PrimeCheck.java) + - 📄 [PrimeFactorization](src/main/java/com/thealgorithms/maths/Prime/PrimeFactorization.java) + - 📄 [SquareFreeInteger](src/main/java/com/thealgorithms/maths/Prime/SquareFreeInteger.java) + - 📄 [PronicNumber](src/main/java/com/thealgorithms/maths/PronicNumber.java) + - 📄 [PythagoreanTriple](src/main/java/com/thealgorithms/maths/PythagoreanTriple.java) + - 📄 [QuadraticEquationSolver](src/main/java/com/thealgorithms/maths/QuadraticEquationSolver.java) + - 📄 [ReverseNumber](src/main/java/com/thealgorithms/maths/ReverseNumber.java) + - 📄 [RomanNumeralUtil](src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java) + - 📄 [SecondMinMax](src/main/java/com/thealgorithms/maths/SecondMinMax.java) + - 📄 [SieveOfEratosthenes](src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java) + - 📄 [SimpsonIntegration](src/main/java/com/thealgorithms/maths/SimpsonIntegration.java) + - 📄 [SolovayStrassenPrimalityTest](src/main/java/com/thealgorithms/maths/SolovayStrassenPrimalityTest.java) + - 📄 [SquareRootWithBabylonianMethod](src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java) + - 📄 [SquareRootWithNewtonRaphsonMethod](src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java) + - 📄 [StandardDeviation](src/main/java/com/thealgorithms/maths/StandardDeviation.java) + - 📄 [StandardScore](src/main/java/com/thealgorithms/maths/StandardScore.java) + - 📄 [StrobogrammaticNumber](src/main/java/com/thealgorithms/maths/StrobogrammaticNumber.java) + - 📄 [SumOfArithmeticSeries](src/main/java/com/thealgorithms/maths/SumOfArithmeticSeries.java) + - 📄 [SumOfDigits](src/main/java/com/thealgorithms/maths/SumOfDigits.java) + - 📄 [SumOfOddNumbers](src/main/java/com/thealgorithms/maths/SumOfOddNumbers.java) + - 📄 [SumWithoutArithmeticOperators](src/main/java/com/thealgorithms/maths/SumWithoutArithmeticOperators.java) + - 📄 [TrinomialTriangle](src/main/java/com/thealgorithms/maths/TrinomialTriangle.java) + - 📄 [TwinPrime](src/main/java/com/thealgorithms/maths/TwinPrime.java) + - 📄 [UniformNumbers](src/main/java/com/thealgorithms/maths/UniformNumbers.java) + - 📄 [VampireNumber](src/main/java/com/thealgorithms/maths/VampireNumber.java) + - 📄 [VectorCrossProduct](src/main/java/com/thealgorithms/maths/VectorCrossProduct.java) + - 📄 [Volume](src/main/java/com/thealgorithms/maths/Volume.java) + - 📁 **matrix** + - 📄 [InverseOfMatrix](src/main/java/com/thealgorithms/matrix/InverseOfMatrix.java) + - 📄 [MatrixRank](src/main/java/com/thealgorithms/matrix/MatrixRank.java) + - 📄 [MatrixTranspose](src/main/java/com/thealgorithms/matrix/MatrixTranspose.java) + - 📄 [MedianOfMatrix](src/main/java/com/thealgorithms/matrix/MedianOfMatrix.java) + - 📄 [MirrorOfMatrix](src/main/java/com/thealgorithms/matrix/MirrorOfMatrix.java) + - 📄 [PrintAMatrixInSpiralOrder](src/main/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrder.java) + - 📄 [RotateMatrixBy90Degrees](src/main/java/com/thealgorithms/matrix/RotateMatrixBy90Degrees.java) + - 📄 [SolveSystem](src/main/java/com/thealgorithms/matrix/SolveSystem.java) + - 📁 **matrixexponentiation** + - 📄 [Fibonacci](src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java) + - 📁 **utils** + - 📄 [MatrixUtil](src/main/java/com/thealgorithms/matrix/utils/MatrixUtil.java) + - 📁 **misc** + - 📄 [ColorContrastRatio](src/main/java/com/thealgorithms/misc/ColorContrastRatio.java) + - 📄 [MapReduce](src/main/java/com/thealgorithms/misc/MapReduce.java) + - 📄 [MedianOfRunningArray](src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java) + - 📄 [MedianOfRunningArrayByte](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java) + - 📄 [MedianOfRunningArrayDouble](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java) + - 📄 [MedianOfRunningArrayFloat](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java) + - 📄 [MedianOfRunningArrayInteger](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java) + - 📄 [MedianOfRunningArrayLong](src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java) + - 📄 [PalindromePrime](src/main/java/com/thealgorithms/misc/PalindromePrime.java) + - 📄 [PalindromeSinglyLinkedList](src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java) + - 📄 [RangeInSortedArray](src/main/java/com/thealgorithms/misc/RangeInSortedArray.java) + - 📄 [ShuffleArray](src/main/java/com/thealgorithms/misc/ShuffleArray.java) + - 📄 [Sparsity](src/main/java/com/thealgorithms/misc/Sparsity.java) + - 📄 [ThreeSumProblem](src/main/java/com/thealgorithms/misc/ThreeSumProblem.java) + - 📄 [TwoSumProblem](src/main/java/com/thealgorithms/misc/TwoSumProblem.java) + - 📁 **others** + - 📄 [ArrayLeftRotation](src/main/java/com/thealgorithms/others/ArrayLeftRotation.java) + - 📄 [ArrayRightRotation](src/main/java/com/thealgorithms/others/ArrayRightRotation.java) + - 📄 [BFPRT](src/main/java/com/thealgorithms/others/BFPRT.java) + - 📄 [BankersAlgorithm](src/main/java/com/thealgorithms/others/BankersAlgorithm.java) + - 📄 [BoyerMoore](src/main/java/com/thealgorithms/others/BoyerMoore.java) + - 📄 [BrianKernighanAlgorithm](src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java) + - 📄 [CRC16](src/main/java/com/thealgorithms/others/CRC16.java) + - 📄 [CRC32](src/main/java/com/thealgorithms/others/CRC32.java) + - 📄 [CRCAlgorithm](src/main/java/com/thealgorithms/others/CRCAlgorithm.java) + - 📄 [Conway](src/main/java/com/thealgorithms/others/Conway.java) + - 📄 [Damm](src/main/java/com/thealgorithms/others/Damm.java) + - 📄 [Dijkstra](src/main/java/com/thealgorithms/others/Dijkstra.java) + - 📄 [FloydTriangle](src/main/java/com/thealgorithms/others/FloydTriangle.java) + - 📄 [GaussLegendre](src/main/java/com/thealgorithms/others/GaussLegendre.java) + - 📄 [HappyNumbersSeq](src/main/java/com/thealgorithms/others/HappyNumbersSeq.java) + - 📄 [Huffman](src/main/java/com/thealgorithms/others/Huffman.java) + - 📄 [Implementing_auto_completing_features_using_trie](src/main/java/com/thealgorithms/others/Implementing_auto_completing_features_using_trie.java) + - 📄 [InsertDeleteInArray](src/main/java/com/thealgorithms/others/InsertDeleteInArray.java) + - 📄 [KochSnowflake](src/main/java/com/thealgorithms/others/KochSnowflake.java) + - 📄 [Krishnamurthy](src/main/java/com/thealgorithms/others/Krishnamurthy.java) + - 📄 [LineSweep](src/main/java/com/thealgorithms/others/LineSweep.java) + - 📄 [LinearCongruentialGenerator](src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java) + - 📄 [LowestBasePalindrome](src/main/java/com/thealgorithms/others/LowestBasePalindrome.java) + - 📄 [Luhn](src/main/java/com/thealgorithms/others/Luhn.java) + - 📄 [Mandelbrot](src/main/java/com/thealgorithms/others/Mandelbrot.java) + - 📄 [MaximumSlidingWindow](src/main/java/com/thealgorithms/others/MaximumSlidingWindow.java) + - 📄 [MaximumSumOfDistinctSubarraysWithLengthK](src/main/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthK.java) + - 📄 [MemoryManagementAlgorithms](src/main/java/com/thealgorithms/others/MemoryManagementAlgorithms.java) + - 📄 [MiniMaxAlgorithm](src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java) + - 📄 [PageRank](src/main/java/com/thealgorithms/others/PageRank.java) + - 📄 [PasswordGen](src/main/java/com/thealgorithms/others/PasswordGen.java) + - 📄 [PerlinNoise](src/main/java/com/thealgorithms/others/PerlinNoise.java) + - 📄 [PrintAMatrixInSpiralOrder](src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java) + - 📄 [QueueUsingTwoStacks](src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java) + - 📄 [RemoveDuplicateFromString](src/main/java/com/thealgorithms/others/RemoveDuplicateFromString.java) + - 📄 [ReverseStackUsingRecursion](src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java) + - 📄 [SkylineProblem](src/main/java/com/thealgorithms/others/SkylineProblem.java) + - 📄 [TwoPointers](src/main/java/com/thealgorithms/others/TwoPointers.java) + - 📄 [Verhoeff](src/main/java/com/thealgorithms/others/Verhoeff.java) + - 📁 **cn** + - 📄 [HammingDistance](src/main/java/com/thealgorithms/others/cn/HammingDistance.java) + - 📁 **puzzlesandgames** + - 📄 [Sudoku](src/main/java/com/thealgorithms/puzzlesandgames/Sudoku.java) + - 📄 [TowerOfHanoi](src/main/java/com/thealgorithms/puzzlesandgames/TowerOfHanoi.java) + - 📄 [WordBoggle](src/main/java/com/thealgorithms/puzzlesandgames/WordBoggle.java) + - 📁 **randomized** + - 📄 [KargerMinCut](src/main/java/com/thealgorithms/randomized/KargerMinCut.java) + - 📄 [MonteCarloIntegration](src/main/java/com/thealgorithms/randomized/MonteCarloIntegration.java) + - 📄 [RandomizedQuickSort](src/main/java/com/thealgorithms/randomized/RandomizedQuickSort.java) + - 📄 [ReservoirSampling](src/main/java/com/thealgorithms/randomized/ReservoirSampling.java) + - 📁 **recursion** + - 📄 [FibonacciSeries](src/main/java/com/thealgorithms/recursion/FibonacciSeries.java) + - 📄 [GenerateSubsets](src/main/java/com/thealgorithms/recursion/GenerateSubsets.java) + - 📁 **scheduling** + - 📄 [AgingScheduling](src/main/java/com/thealgorithms/scheduling/AgingScheduling.java) + - 📄 [EDFScheduling](src/main/java/com/thealgorithms/scheduling/EDFScheduling.java) + - 📄 [FCFSScheduling](src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java) + - 📄 [FairShareScheduling](src/main/java/com/thealgorithms/scheduling/FairShareScheduling.java) + - 📄 [GangScheduling](src/main/java/com/thealgorithms/scheduling/GangScheduling.java) + - 📄 [HighestResponseRatioNextScheduling](src/main/java/com/thealgorithms/scheduling/HighestResponseRatioNextScheduling.java) + - 📄 [JobSchedulingWithDeadline](src/main/java/com/thealgorithms/scheduling/JobSchedulingWithDeadline.java) + - 📄 [LotteryScheduling](src/main/java/com/thealgorithms/scheduling/LotteryScheduling.java) + - 📄 [MLFQScheduler](src/main/java/com/thealgorithms/scheduling/MLFQScheduler.java) + - 📄 [MultiAgentScheduling](src/main/java/com/thealgorithms/scheduling/MultiAgentScheduling.java) + - 📄 [NonPreemptivePriorityScheduling](src/main/java/com/thealgorithms/scheduling/NonPreemptivePriorityScheduling.java) + - 📄 [PreemptivePriorityScheduling](src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java) + - 📄 [ProportionalFairScheduling](src/main/java/com/thealgorithms/scheduling/ProportionalFairScheduling.java) + - 📄 [RRScheduling](src/main/java/com/thealgorithms/scheduling/RRScheduling.java) + - 📄 [RandomScheduling](src/main/java/com/thealgorithms/scheduling/RandomScheduling.java) + - 📄 [SJFScheduling](src/main/java/com/thealgorithms/scheduling/SJFScheduling.java) + - 📄 [SRTFScheduling](src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java) + - 📄 [SelfAdjustingScheduling](src/main/java/com/thealgorithms/scheduling/SelfAdjustingScheduling.java) + - 📄 [SlackTimeScheduling](src/main/java/com/thealgorithms/scheduling/SlackTimeScheduling.java) + - 📁 **diskscheduling** + - 📄 [CircularLookScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/CircularLookScheduling.java) + - 📄 [CircularScanScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/CircularScanScheduling.java) + - 📄 [LookScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/LookScheduling.java) + - 📄 [SSFScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/SSFScheduling.java) + - 📄 [ScanScheduling](src/main/java/com/thealgorithms/scheduling/diskscheduling/ScanScheduling.java) + - 📁 **searches** + - 📄 [BM25InvertedIndex](src/main/java/com/thealgorithms/searches/BM25InvertedIndex.java) + - 📄 [BinarySearch](src/main/java/com/thealgorithms/searches/BinarySearch.java) + - 📄 [BinarySearch2dArray](src/main/java/com/thealgorithms/searches/BinarySearch2dArray.java) + - 📄 [BoyerMoore](src/main/java/com/thealgorithms/searches/BoyerMoore.java) + - 📄 [BreadthFirstSearch](src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java) + - 📄 [DepthFirstSearch](src/main/java/com/thealgorithms/searches/DepthFirstSearch.java) + - 📄 [ExponentalSearch](src/main/java/com/thealgorithms/searches/ExponentalSearch.java) + - 📄 [FibonacciSearch](src/main/java/com/thealgorithms/searches/FibonacciSearch.java) + - 📄 [HowManyTimesRotated](src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java) + - 📄 [InterpolationSearch](src/main/java/com/thealgorithms/searches/InterpolationSearch.java) + - 📄 [IterativeBinarySearch](src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java) + - 📄 [IterativeTernarySearch](src/main/java/com/thealgorithms/searches/IterativeTernarySearch.java) + - 📄 [JumpSearch](src/main/java/com/thealgorithms/searches/JumpSearch.java) + - 📄 [KMPSearch](src/main/java/com/thealgorithms/searches/KMPSearch.java) + - 📄 [LinearSearch](src/main/java/com/thealgorithms/searches/LinearSearch.java) + - 📄 [LinearSearchThread](src/main/java/com/thealgorithms/searches/LinearSearchThread.java) + - 📄 [LowerBound](src/main/java/com/thealgorithms/searches/LowerBound.java) + - 📄 [MonteCarloTreeSearch](src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java) + - 📄 [OrderAgnosticBinarySearch](src/main/java/com/thealgorithms/searches/OrderAgnosticBinarySearch.java) + - 📄 [PerfectBinarySearch](src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java) + - 📄 [QuickSelect](src/main/java/com/thealgorithms/searches/QuickSelect.java) + - 📄 [RabinKarpAlgorithm](src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java) + - 📄 [RandomSearch](src/main/java/com/thealgorithms/searches/RandomSearch.java) + - 📄 [RecursiveBinarySearch](src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java) + - 📄 [RowColumnWiseSorted2dArrayBinarySearch](src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java) + - 📄 [SaddlebackSearch](src/main/java/com/thealgorithms/searches/SaddlebackSearch.java) + - 📄 [SearchInARowAndColWiseSortedMatrix](src/main/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrix.java) + - 📄 [SortOrderAgnosticBinarySearch](src/main/java/com/thealgorithms/searches/SortOrderAgnosticBinarySearch.java) + - 📄 [SquareRootBinarySearch](src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java) + - 📄 [TernarySearch](src/main/java/com/thealgorithms/searches/TernarySearch.java) + - 📄 [UnionFind](src/main/java/com/thealgorithms/searches/UnionFind.java) + - 📄 [UpperBound](src/main/java/com/thealgorithms/searches/UpperBound.java) + - 📁 **slidingwindow** + - 📄 [LongestSubarrayWithSumLessOrEqualToK](src/main/java/com/thealgorithms/slidingwindow/LongestSubarrayWithSumLessOrEqualToK.java) + - 📄 [LongestSubstringWithoutRepeatingCharacters](src/main/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java) + - 📄 [MaxSumKSizeSubarray](src/main/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarray.java) + - 📄 [MinSumKSizeSubarray](src/main/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarray.java) + - 📄 [ShortestCoprimeSegment](src/main/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegment.java) + - 📁 **sorts** + - 📄 [AdaptiveMergeSort](src/main/java/com/thealgorithms/sorts/AdaptiveMergeSort.java) + - 📄 [BeadSort](src/main/java/com/thealgorithms/sorts/BeadSort.java) + - 📄 [BinaryInsertionSort](src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java) + - 📄 [BitonicSort](src/main/java/com/thealgorithms/sorts/BitonicSort.java) + - 📄 [BogoSort](src/main/java/com/thealgorithms/sorts/BogoSort.java) + - 📄 [BubbleSort](src/main/java/com/thealgorithms/sorts/BubbleSort.java) + - 📄 [BubbleSortRecursive](src/main/java/com/thealgorithms/sorts/BubbleSortRecursive.java) + - 📄 [BucketSort](src/main/java/com/thealgorithms/sorts/BucketSort.java) + - 📄 [CircleSort](src/main/java/com/thealgorithms/sorts/CircleSort.java) + - 📄 [CocktailShakerSort](src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java) + - 📄 [CombSort](src/main/java/com/thealgorithms/sorts/CombSort.java) + - 📄 [CountingSort](src/main/java/com/thealgorithms/sorts/CountingSort.java) + - 📄 [CycleSort](src/main/java/com/thealgorithms/sorts/CycleSort.java) + - 📄 [DarkSort](src/main/java/com/thealgorithms/sorts/DarkSort.java) + - 📄 [DualPivotQuickSort](src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java) + - 📄 [DutchNationalFlagSort](src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java) + - 📄 [ExchangeSort](src/main/java/com/thealgorithms/sorts/ExchangeSort.java) + - 📄 [FlashSort](src/main/java/com/thealgorithms/sorts/FlashSort.java) + - 📄 [GnomeSort](src/main/java/com/thealgorithms/sorts/GnomeSort.java) + - 📄 [HeapSort](src/main/java/com/thealgorithms/sorts/HeapSort.java) + - 📄 [InsertionSort](src/main/java/com/thealgorithms/sorts/InsertionSort.java) + - 📄 [IntrospectiveSort](src/main/java/com/thealgorithms/sorts/IntrospectiveSort.java) + - 📄 [LinkListSort](src/main/java/com/thealgorithms/sorts/LinkListSort.java) + - 📄 [MergeSort](src/main/java/com/thealgorithms/sorts/MergeSort.java) + - 📄 [MergeSortNoExtraSpace](src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java) + - 📄 [MergeSortRecursive](src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java) + - 📄 [OddEvenSort](src/main/java/com/thealgorithms/sorts/OddEvenSort.java) + - 📄 [PancakeSort](src/main/java/com/thealgorithms/sorts/PancakeSort.java) + - 📄 [PatienceSort](src/main/java/com/thealgorithms/sorts/PatienceSort.java) + - 📄 [PigeonholeSort](src/main/java/com/thealgorithms/sorts/PigeonholeSort.java) + - 📄 [QuickSort](src/main/java/com/thealgorithms/sorts/QuickSort.java) + - 📄 [RadixSort](src/main/java/com/thealgorithms/sorts/RadixSort.java) + - 📄 [SelectionSort](src/main/java/com/thealgorithms/sorts/SelectionSort.java) + - 📄 [SelectionSortRecursive](src/main/java/com/thealgorithms/sorts/SelectionSortRecursive.java) + - 📄 [ShellSort](src/main/java/com/thealgorithms/sorts/ShellSort.java) + - 📄 [SimpleSort](src/main/java/com/thealgorithms/sorts/SimpleSort.java) + - 📄 [SlowSort](src/main/java/com/thealgorithms/sorts/SlowSort.java) + - 📄 [SortAlgorithm](src/main/java/com/thealgorithms/sorts/SortAlgorithm.java) + - 📄 [SortUtils](src/main/java/com/thealgorithms/sorts/SortUtils.java) + - 📄 [SortUtilsRandomGenerator](src/main/java/com/thealgorithms/sorts/SortUtilsRandomGenerator.java) + - 📄 [SpreadSort](src/main/java/com/thealgorithms/sorts/SpreadSort.java) + - 📄 [StalinSort](src/main/java/com/thealgorithms/sorts/StalinSort.java) + - 📄 [StoogeSort](src/main/java/com/thealgorithms/sorts/StoogeSort.java) + - 📄 [StrandSort](src/main/java/com/thealgorithms/sorts/StrandSort.java) + - 📄 [SwapSort](src/main/java/com/thealgorithms/sorts/SwapSort.java) + - 📄 [TimSort](src/main/java/com/thealgorithms/sorts/TimSort.java) + - 📄 [TopologicalSort](src/main/java/com/thealgorithms/sorts/TopologicalSort.java) + - 📄 [TreeSort](src/main/java/com/thealgorithms/sorts/TreeSort.java) + - 📄 [WaveSort](src/main/java/com/thealgorithms/sorts/WaveSort.java) + - 📄 [WiggleSort](src/main/java/com/thealgorithms/sorts/WiggleSort.java) + - 📁 **stacks** + - 📄 [BalancedBrackets](src/main/java/com/thealgorithms/stacks/BalancedBrackets.java) + - 📄 [CelebrityFinder](src/main/java/com/thealgorithms/stacks/CelebrityFinder.java) + - 📄 [DecimalToAnyUsingStack](src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java) + - 📄 [DuplicateBrackets](src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java) + - 📄 [GreatestElementConstantTime](src/main/java/com/thealgorithms/stacks/GreatestElementConstantTime.java) + - 📄 [InfixToPostfix](src/main/java/com/thealgorithms/stacks/InfixToPostfix.java) + - 📄 [InfixToPrefix](src/main/java/com/thealgorithms/stacks/InfixToPrefix.java) + - 📄 [LargestRectangle](src/main/java/com/thealgorithms/stacks/LargestRectangle.java) + - 📄 [MaximumMinimumWindow](src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java) + - 📄 [MinStackUsingSingleStack](src/main/java/com/thealgorithms/stacks/MinStackUsingSingleStack.java) + - 📄 [MinStackUsingTwoStacks](src/main/java/com/thealgorithms/stacks/MinStackUsingTwoStacks.java) + - 📄 [NextGreaterElement](src/main/java/com/thealgorithms/stacks/NextGreaterElement.java) + - 📄 [NextSmallerElement](src/main/java/com/thealgorithms/stacks/NextSmallerElement.java) + - 📄 [PalindromeWithStack](src/main/java/com/thealgorithms/stacks/PalindromeWithStack.java) + - 📄 [PostfixEvaluator](src/main/java/com/thealgorithms/stacks/PostfixEvaluator.java) + - 📄 [PostfixToInfix](src/main/java/com/thealgorithms/stacks/PostfixToInfix.java) + - 📄 [PrefixEvaluator](src/main/java/com/thealgorithms/stacks/PrefixEvaluator.java) + - 📄 [PrefixToInfix](src/main/java/com/thealgorithms/stacks/PrefixToInfix.java) + - 📄 [SmallestElementConstantTime](src/main/java/com/thealgorithms/stacks/SmallestElementConstantTime.java) + - 📄 [SortStack](src/main/java/com/thealgorithms/stacks/SortStack.java) + - 📄 [StackPostfixNotation](src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java) + - 📄 [StackUsingTwoQueues](src/main/java/com/thealgorithms/stacks/StackUsingTwoQueues.java) + - 📁 **strings** + - 📄 [AhoCorasick](src/main/java/com/thealgorithms/strings/AhoCorasick.java) + - 📄 [Alphabetical](src/main/java/com/thealgorithms/strings/Alphabetical.java) + - 📄 [Anagrams](src/main/java/com/thealgorithms/strings/Anagrams.java) + - 📄 [CharactersSame](src/main/java/com/thealgorithms/strings/CharactersSame.java) + - 📄 [CheckVowels](src/main/java/com/thealgorithms/strings/CheckVowels.java) + - 📄 [CountChar](src/main/java/com/thealgorithms/strings/CountChar.java) + - 📄 [CountWords](src/main/java/com/thealgorithms/strings/CountWords.java) + - 📄 [HammingDistance](src/main/java/com/thealgorithms/strings/HammingDistance.java) + - 📄 [HorspoolSearch](src/main/java/com/thealgorithms/strings/HorspoolSearch.java) + - 📄 [Isomorphic](src/main/java/com/thealgorithms/strings/Isomorphic.java) + - 📄 [KMP](src/main/java/com/thealgorithms/strings/KMP.java) + - 📄 [LetterCombinationsOfPhoneNumber](src/main/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumber.java) + - 📄 [LongestCommonPrefix](src/main/java/com/thealgorithms/strings/LongestCommonPrefix.java) + - 📄 [LongestNonRepetitiveSubstring](src/main/java/com/thealgorithms/strings/LongestNonRepetitiveSubstring.java) + - 📄 [LongestPalindromicSubstring](src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java) + - 📄 [Lower](src/main/java/com/thealgorithms/strings/Lower.java) + - 📄 [Manacher](src/main/java/com/thealgorithms/strings/Manacher.java) + - 📄 [MyAtoi](src/main/java/com/thealgorithms/strings/MyAtoi.java) + - 📄 [Palindrome](src/main/java/com/thealgorithms/strings/Palindrome.java) + - 📄 [Pangram](src/main/java/com/thealgorithms/strings/Pangram.java) + - 📄 [PermuteString](src/main/java/com/thealgorithms/strings/PermuteString.java) + - 📄 [RabinKarp](src/main/java/com/thealgorithms/strings/RabinKarp.java) + - 📄 [ReturnSubsequence](src/main/java/com/thealgorithms/strings/ReturnSubsequence.java) + - 📄 [ReverseString](src/main/java/com/thealgorithms/strings/ReverseString.java) + - 📄 [ReverseStringRecursive](src/main/java/com/thealgorithms/strings/ReverseStringRecursive.java) + - 📄 [ReverseWordsInString](src/main/java/com/thealgorithms/strings/ReverseWordsInString.java) + - 📄 [Rotation](src/main/java/com/thealgorithms/strings/Rotation.java) + - 📄 [StringCompression](src/main/java/com/thealgorithms/strings/StringCompression.java) + - 📄 [StringMatchFiniteAutomata](src/main/java/com/thealgorithms/strings/StringMatchFiniteAutomata.java) + - 📄 [Upper](src/main/java/com/thealgorithms/strings/Upper.java) + - 📄 [ValidParentheses](src/main/java/com/thealgorithms/strings/ValidParentheses.java) + - 📄 [WordLadder](src/main/java/com/thealgorithms/strings/WordLadder.java) + - 📁 **zigZagPattern** + - 📄 [README](src/main/java/com/thealgorithms/strings/zigZagPattern/README.md) + - 📄 [ZigZagPattern](src/main/java/com/thealgorithms/strings/zigZagPattern/ZigZagPattern.java) + - 📁 **tree** + - 📄 [HeavyLightDecomposition](src/main/java/com/thealgorithms/tree/HeavyLightDecomposition.java) +- 📁 **test** + - 📁 **java** + - 📁 **com** + - 📁 **thealgorithms** + - 📁 **audiofilters** + - 📄 [EMAFilterTest](src/test/java/com/thealgorithms/audiofilters/EMAFilterTest.java) + - 📄 [IIRFilterTest](src/test/java/com/thealgorithms/audiofilters/IIRFilterTest.java) + - 📁 **backtracking** + - 📄 [AllPathsFromSourceToTargetTest](src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java) + - 📄 [ArrayCombinationTest](src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java) + - 📄 [CombinationTest](src/test/java/com/thealgorithms/backtracking/CombinationTest.java) + - 📄 [CrosswordSolverTest](src/test/java/com/thealgorithms/backtracking/CrosswordSolverTest.java) + - 📄 [FloodFillTest](src/test/java/com/thealgorithms/backtracking/FloodFillTest.java) + - 📄 [KnightsTourTest](src/test/java/com/thealgorithms/backtracking/KnightsTourTest.java) + - 📄 [MColoringTest](src/test/java/com/thealgorithms/backtracking/MColoringTest.java) + - 📄 [MazeRecursionTest](src/test/java/com/thealgorithms/backtracking/MazeRecursionTest.java) + - 📄 [NQueensTest](src/test/java/com/thealgorithms/backtracking/NQueensTest.java) + - 📄 [ParenthesesGeneratorTest](src/test/java/com/thealgorithms/backtracking/ParenthesesGeneratorTest.java) + - 📄 [PermutationTest](src/test/java/com/thealgorithms/backtracking/PermutationTest.java) + - 📄 [PowerSumTest](src/test/java/com/thealgorithms/backtracking/PowerSumTest.java) + - 📄 [SubsequenceFinderTest](src/test/java/com/thealgorithms/backtracking/SubsequenceFinderTest.java) + - 📄 [WordPatternMatcherTest](src/test/java/com/thealgorithms/backtracking/WordPatternMatcherTest.java) + - 📄 [WordSearchTest](src/test/java/com/thealgorithms/backtracking/WordSearchTest.java) + - 📁 **bitmanipulation** + - 📄 [BcdConversionTest](src/test/java/com/thealgorithms/bitmanipulation/BcdConversionTest.java) + - 📄 [BinaryPalindromeCheckTest](src/test/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheckTest.java) + - 📄 [BitSwapTest](src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java) + - 📄 [BooleanAlgebraGatesTest](src/test/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGatesTest.java) + - 📄 [ClearLeftmostSetBitTest](src/test/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBitTest.java) + - 📄 [CountLeadingZerosTest](src/test/java/com/thealgorithms/bitmanipulation/CountLeadingZerosTest.java) + - 📄 [CountSetBitsTest](src/test/java/com/thealgorithms/bitmanipulation/CountSetBitsTest.java) + - 📄 [FindNthBitTest](src/test/java/com/thealgorithms/bitmanipulation/FindNthBitTest.java) + - 📄 [FirstDifferentBitTest](src/test/java/com/thealgorithms/bitmanipulation/FirstDifferentBitTest.java) + - 📄 [GenerateSubsetsTest](src/test/java/com/thealgorithms/bitmanipulation/GenerateSubsetsTest.java) + - 📄 [GrayCodeConversionTest](src/test/java/com/thealgorithms/bitmanipulation/GrayCodeConversionTest.java) + - 📄 [HammingDistanceTest](src/test/java/com/thealgorithms/bitmanipulation/HammingDistanceTest.java) + - 📄 [HigherLowerPowerOfTwoTest](src/test/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwoTest.java) + - 📄 [HighestSetBitTest](src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java) + - 📄 [IndexOfRightMostSetBitTest](src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java) + - 📄 [IsEvenTest](src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java) + - 📄 [IsPowerTwoTest](src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java) + - 📄 [LowestSetBitTest](src/test/java/com/thealgorithms/bitmanipulation/LowestSetBitTest.java) + - 📄 [ModuloPowerOfTwoTest](src/test/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwoTest.java) + - 📄 [NextHigherSameBitCountTest](src/test/java/com/thealgorithms/bitmanipulation/NextHigherSameBitCountTest.java) + - 📄 [NonRepeatingNumberFinderTest](src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java) + - 📄 [NumberAppearingOddTimesTest](src/test/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimesTest.java) + - 📄 [NumbersDifferentSignsTest](src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java) + - 📄 [OneBitDifferenceTest](src/test/java/com/thealgorithms/bitmanipulation/OneBitDifferenceTest.java) + - 📄 [OnesComplementTest](src/test/java/com/thealgorithms/bitmanipulation/OnesComplementTest.java) + - 📄 [ParityCheckTest](src/test/java/com/thealgorithms/bitmanipulation/ParityCheckTest.java) + - 📄 [ReverseBitsTest](src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java) + - 📄 [SingleBitOperationsTest](src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java) + - 📄 [SingleElementTest](src/test/java/com/thealgorithms/bitmanipulation/SingleElementTest.java) + - 📄 [SwapAdjacentBitsTest](src/test/java/com/thealgorithms/bitmanipulation/SwapAdjacentBitsTest.java) + - 📄 [TwosComplementTest](src/test/java/com/thealgorithms/bitmanipulation/TwosComplementTest.java) + - 📄 [Xs3ConversionTest](src/test/java/com/thealgorithms/bitmanipulation/Xs3ConversionTest.java) + - 📁 **ciphers** + - 📄 [ADFGVXCipherTest](src/test/java/com/thealgorithms/ciphers/ADFGVXCipherTest.java) + - 📄 [AESEncryptionTest](src/test/java/com/thealgorithms/ciphers/AESEncryptionTest.java) + - 📄 [AffineCipherTest](src/test/java/com/thealgorithms/ciphers/AffineCipherTest.java) + - 📄 [AtbashTest](src/test/java/com/thealgorithms/ciphers/AtbashTest.java) + - 📄 [AutokeyTest](src/test/java/com/thealgorithms/ciphers/AutokeyTest.java) + - 📄 [BaconianCipherTest](src/test/java/com/thealgorithms/ciphers/BaconianCipherTest.java) + - 📄 [BlowfishTest](src/test/java/com/thealgorithms/ciphers/BlowfishTest.java) + - 📄 [CaesarTest](src/test/java/com/thealgorithms/ciphers/CaesarTest.java) + - 📄 [ColumnarTranspositionCipherTest](src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherTest.java) + - 📄 [DESTest](src/test/java/com/thealgorithms/ciphers/DESTest.java) + - 📄 [DiffieHellmanTest](src/test/java/com/thealgorithms/ciphers/DiffieHellmanTest.java) + - 📄 [ECCTest](src/test/java/com/thealgorithms/ciphers/ECCTest.java) + - 📄 [HillCipherTest](src/test/java/com/thealgorithms/ciphers/HillCipherTest.java) + - 📄 [MonoAlphabeticTest](src/test/java/com/thealgorithms/ciphers/MonoAlphabeticTest.java) + - 📄 [PlayfairTest](src/test/java/com/thealgorithms/ciphers/PlayfairTest.java) + - 📄 [PolybiusTest](src/test/java/com/thealgorithms/ciphers/PolybiusTest.java) + - 📄 [RSATest](src/test/java/com/thealgorithms/ciphers/RSATest.java) + - 📄 [RailFenceTest](src/test/java/com/thealgorithms/ciphers/RailFenceTest.java) + - 📄 [SimpleSubCipherTest](src/test/java/com/thealgorithms/ciphers/SimpleSubCipherTest.java) + - 📄 [VigenereTest](src/test/java/com/thealgorithms/ciphers/VigenereTest.java) + - 📄 [XORCipherTest](src/test/java/com/thealgorithms/ciphers/XORCipherTest.java) + - 📁 **a5** + - 📄 [A5CipherTest](src/test/java/com/thealgorithms/ciphers/a5/A5CipherTest.java) + - 📄 [A5KeyStreamGeneratorTest](src/test/java/com/thealgorithms/ciphers/a5/A5KeyStreamGeneratorTest.java) + - 📄 [LFSRTest](src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java) + - 📁 **conversions** + - 📄 [AffineConverterTest](src/test/java/com/thealgorithms/conversions/AffineConverterTest.java) + - 📄 [AnyBaseToDecimalTest](src/test/java/com/thealgorithms/conversions/AnyBaseToDecimalTest.java) + - 📄 [AnytoAnyTest](src/test/java/com/thealgorithms/conversions/AnytoAnyTest.java) + - 📄 [BinaryToDecimalTest](src/test/java/com/thealgorithms/conversions/BinaryToDecimalTest.java) + - 📄 [BinaryToHexadecimalTest](src/test/java/com/thealgorithms/conversions/BinaryToHexadecimalTest.java) + - 📄 [BinaryToOctalTest](src/test/java/com/thealgorithms/conversions/BinaryToOctalTest.java) + - 📄 [DecimalToAnyBaseTest](src/test/java/com/thealgorithms/conversions/DecimalToAnyBaseTest.java) + - 📄 [DecimalToBinaryTest](src/test/java/com/thealgorithms/conversions/DecimalToBinaryTest.java) + - 📄 [DecimalToHexadecimalTest](src/test/java/com/thealgorithms/conversions/DecimalToHexadecimalTest.java) + - 📄 [DecimalToOctalTest](src/test/java/com/thealgorithms/conversions/DecimalToOctalTest.java) + - 📄 [EndianConverterTest](src/test/java/com/thealgorithms/conversions/EndianConverterTest.java) + - 📄 [HexToOctTest](src/test/java/com/thealgorithms/conversions/HexToOctTest.java) + - 📄 [HexaDecimalToBinaryTest](src/test/java/com/thealgorithms/conversions/HexaDecimalToBinaryTest.java) + - 📄 [HexaDecimalToDecimalTest](src/test/java/com/thealgorithms/conversions/HexaDecimalToDecimalTest.java) + - 📄 [IPConverterTest](src/test/java/com/thealgorithms/conversions/IPConverterTest.java) + - 📄 [IPv6ConverterTest](src/test/java/com/thealgorithms/conversions/IPv6ConverterTest.java) + - 📄 [IntegerToEnglishTest](src/test/java/com/thealgorithms/conversions/IntegerToEnglishTest.java) + - 📄 [IntegerToRomanTest](src/test/java/com/thealgorithms/conversions/IntegerToRomanTest.java) + - 📄 [MorseCodeConverterTest](src/test/java/com/thealgorithms/conversions/MorseCodeConverterTest.java) + - 📄 [NumberToWordsTest](src/test/java/com/thealgorithms/conversions/NumberToWordsTest.java) + - 📄 [OctalToBinaryTest](src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java) + - 📄 [OctalToDecimalTest](src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java) + - 📄 [OctalToHexadecimalTest](src/test/java/com/thealgorithms/conversions/OctalToHexadecimalTest.java) + - 📄 [PhoneticAlphabetConverterTest](src/test/java/com/thealgorithms/conversions/PhoneticAlphabetConverterTest.java) + - 📄 [RomanToIntegerTest](src/test/java/com/thealgorithms/conversions/RomanToIntegerTest.java) + - 📄 [TurkishToLatinConversionTest](src/test/java/com/thealgorithms/conversions/TurkishToLatinConversionTest.java) + - 📄 [UnitConversionsTest](src/test/java/com/thealgorithms/conversions/UnitConversionsTest.java) + - 📄 [UnitsConverterTest](src/test/java/com/thealgorithms/conversions/UnitsConverterTest.java) + - 📄 [WordsToNumberTest](src/test/java/com/thealgorithms/conversions/WordsToNumberTest.java) + - 📁 **datastructures** + - 📁 **bag** + - 📄 [BagTest](src/test/java/com/thealgorithms/datastructures/bag/BagTest.java) + - 📁 **bloomfilter** + - 📄 [BloomFilterTest](src/test/java/com/thealgorithms/datastructures/bloomfilter/BloomFilterTest.java) + - 📁 **buffers** + - 📄 [CircularBufferTest](src/test/java/com/thealgorithms/datastructures/buffers/CircularBufferTest.java) + - 📁 **caches** + - 📄 [LFUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/LFUCacheTest.java) + - 📄 [LRUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java) + - 📄 [MRUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java) + - 📁 **crdt** + - 📄 [GCounterTest](src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java) + - 📄 [GSetTest](src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java) + - 📄 [LWWElementSetTest](src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java) + - 📄 [ORSetTest](src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java) + - 📄 [PNCounterTest](src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java) + - 📄 [TwoPSetTest](src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java) + - 📁 **disjointsetunion** + - 📄 [DisjointSetUnionTest](src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java) + - 📁 **dynamicarray** + - 📄 [DynamicArrayTest](src/test/java/com/thealgorithms/datastructures/dynamicarray/DynamicArrayTest.java) + - 📁 **graphs** + - 📄 [AStarTest](src/test/java/com/thealgorithms/datastructures/graphs/AStarTest.java) + - 📄 [BipartiteGraphDFSTest](src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java) + - 📄 [BoruvkaAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java) + - 📄 [DijkstraAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java) + - 📄 [DijkstraOptimizedAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithmTest.java) + - 📄 [EdmondsBlossomAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithmTest.java) + - 📄 [FloydWarshallTest](src/test/java/com/thealgorithms/datastructures/graphs/FloydWarshallTest.java) + - 📄 [FordFulkersonTest](src/test/java/com/thealgorithms/datastructures/graphs/FordFulkersonTest.java) + - 📄 [HamiltonianCycleTest](src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java) + - 📄 [JohnsonsAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/JohnsonsAlgorithmTest.java) + - 📄 [KahnsAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithmTest.java) + - 📄 [KosarajuTest](src/test/java/com/thealgorithms/datastructures/graphs/KosarajuTest.java) + - 📄 [KruskalTest](src/test/java/com/thealgorithms/datastructures/graphs/KruskalTest.java) + - 📄 [MatrixGraphsTest](src/test/java/com/thealgorithms/datastructures/graphs/MatrixGraphsTest.java) + - 📄 [PrimMSTTest](src/test/java/com/thealgorithms/datastructures/graphs/PrimMSTTest.java) + - 📄 [TarjansAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithmTest.java) + - 📄 [WelshPowellTest](src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java) + - 📁 **hashmap** + - 📁 **hashing** + - 📄 [GenericHashMapUsingArrayListTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayListTest.java) + - 📄 [GenericHashMapUsingArrayTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayTest.java) + - 📄 [HashMapCuckooHashingTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashingTest.java) + - 📄 [HashMapTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapTest.java) + - 📄 [IntersectionTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/IntersectionTest.java) + - 📄 [LinearProbingHashMapTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMapTest.java) + - 📄 [MajorityElementTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElementTest.java) + - 📄 [MapTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MapTest.java) + - 📁 **heaps** + - 📄 [FibonacciHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/FibonacciHeapTest.java) + - 📄 [GenericHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/GenericHeapTest.java) + - 📄 [HeapElementTest](src/test/java/com/thealgorithms/datastructures/heaps/HeapElementTest.java) + - 📄 [KthElementFinderTest](src/test/java/com/thealgorithms/datastructures/heaps/KthElementFinderTest.java) + - 📄 [LeftistHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java) + - 📄 [MaxHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/MaxHeapTest.java) + - 📄 [MedianFinderTest](src/test/java/com/thealgorithms/datastructures/heaps/MedianFinderTest.java) + - 📄 [MergeKSortedArraysTest](src/test/java/com/thealgorithms/datastructures/heaps/MergeKSortedArraysTest.java) + - 📄 [MinHeapTest](src/test/java/com/thealgorithms/datastructures/heaps/MinHeapTest.java) + - 📄 [MinPriorityQueueTest](src/test/java/com/thealgorithms/datastructures/heaps/MinPriorityQueueTest.java) + - 📁 **lists** + - 📄 [CircleLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java) + - 📄 [CountSinglyLinkedListRecursionTest](src/test/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursionTest.java) + - 📄 [CreateAndDetectLoopTest](src/test/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoopTest.java) + - 📄 [CursorLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/CursorLinkedListTest.java) + - 📄 [MergeKSortedLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/MergeKSortedLinkedListTest.java) + - 📄 [MergeSortedArrayListTest](src/test/java/com/thealgorithms/datastructures/lists/MergeSortedArrayListTest.java) + - 📄 [MergeSortedSinglyLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedListTest.java) + - 📄 [QuickSortLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java) + - 📄 [ReverseKGroupTest](src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java) + - 📄 [RotateSinglyLinkedListsTest](src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java) + - 📄 [SearchSinglyLinkedListRecursionTest](src/test/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursionTest.java) + - 📄 [SinglyLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java) + - 📄 [SkipListTest](src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java) + - 📄 [SortedLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/SortedLinkedListTest.java) + - 📁 **queues** + - 📄 [CircularQueueTest](src/test/java/com/thealgorithms/datastructures/queues/CircularQueueTest.java) + - 📄 [DequeTest](src/test/java/com/thealgorithms/datastructures/queues/DequeTest.java) + - 📄 [GenericArrayListQueueTest](src/test/java/com/thealgorithms/datastructures/queues/GenericArrayListQueueTest.java) + - 📄 [LinkedQueueTest](src/test/java/com/thealgorithms/datastructures/queues/LinkedQueueTest.java) + - 📄 [PriorityQueuesTest](src/test/java/com/thealgorithms/datastructures/queues/PriorityQueuesTest.java) + - 📄 [QueueByTwoStacksTest](src/test/java/com/thealgorithms/datastructures/queues/QueueByTwoStacksTest.java) + - 📄 [QueueTest](src/test/java/com/thealgorithms/datastructures/queues/QueueTest.java) + - 📄 [SlidingWindowMaximumTest](src/test/java/com/thealgorithms/datastructures/queues/SlidingWindowMaximumTest.java) + - 📄 [TokenBucketTest](src/test/java/com/thealgorithms/datastructures/queues/TokenBucketTest.java) + - 📁 **stacks** + - 📄 [NodeStackTest](src/test/java/com/thealgorithms/datastructures/stacks/NodeStackTest.java) + - 📄 [ReverseStackTest](src/test/java/com/thealgorithms/datastructures/stacks/ReverseStackTest.java) + - 📄 [StackArrayListTest](src/test/java/com/thealgorithms/datastructures/stacks/StackArrayListTest.java) + - 📄 [StackArrayTest](src/test/java/com/thealgorithms/datastructures/stacks/StackArrayTest.java) + - 📄 [StackOfLinkedListTest](src/test/java/com/thealgorithms/datastructures/stacks/StackOfLinkedListTest.java) + - 📁 **trees** + - 📄 [AVLTreeTest](src/test/java/com/thealgorithms/datastructures/trees/AVLTreeTest.java) + - 📄 [BSTFromSortedArrayTest](src/test/java/com/thealgorithms/datastructures/trees/BSTFromSortedArrayTest.java) + - 📄 [BSTIterativeTest](src/test/java/com/thealgorithms/datastructures/trees/BSTIterativeTest.java) + - 📄 [BSTRecursiveTest](src/test/java/com/thealgorithms/datastructures/trees/BSTRecursiveTest.java) + - 📄 [BTreeTest](src/test/java/com/thealgorithms/datastructures/trees/BTreeTest.java) + - 📄 [BinaryTreeTest](src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeTest.java) + - 📄 [BoundaryTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/BoundaryTraversalTest.java) + - 📄 [CeilInBinarySearchTreeTest](src/test/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTreeTest.java) + - 📄 [CheckBinaryTreeIsValidBSTTest](src/test/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBSTTest.java) + - 📄 [CheckIfBinaryTreeBalancedTest](src/test/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalancedTest.java) + - 📄 [CheckTreeIsSymmetricTest](src/test/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetricTest.java) + - 📄 [CreateBinaryTreeFromInorderPreorderTest](src/test/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorderTest.java) + - 📄 [InorderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/InorderTraversalTest.java) + - 📄 [KDTreeTest](src/test/java/com/thealgorithms/datastructures/trees/KDTreeTest.java) + - 📄 [LazySegmentTreeTest](src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java) + - 📄 [LevelOrderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/LevelOrderTraversalTest.java) + - 📄 [PostOrderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/PostOrderTraversalTest.java) + - 📄 [PreOrderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/PreOrderTraversalTest.java) + - 📄 [QuadTreeTest](src/test/java/com/thealgorithms/datastructures/trees/QuadTreeTest.java) + - 📄 [SameTreesCheckTest](src/test/java/com/thealgorithms/datastructures/trees/SameTreesCheckTest.java) + - 📄 [SplayTreeTest](src/test/java/com/thealgorithms/datastructures/trees/SplayTreeTest.java) + - 📄 [TreapTest](src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java) + - 📄 [TreeTestUtils](src/test/java/com/thealgorithms/datastructures/trees/TreeTestUtils.java) + - 📄 [TrieTest](src/test/java/com/thealgorithms/datastructures/trees/TrieTest.java) + - 📄 [VerticalOrderTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversalTest.java) + - 📄 [ZigzagTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/ZigzagTraversalTest.java) + - 📁 **divideandconquer** + - 📄 [BinaryExponentiationTest](src/test/java/com/thealgorithms/divideandconquer/BinaryExponentiationTest.java) + - 📄 [ClosestPairTest](src/test/java/com/thealgorithms/divideandconquer/ClosestPairTest.java) + - 📄 [CountingInversionsTest](src/test/java/com/thealgorithms/divideandconquer/CountingInversionsTest.java) + - 📄 [MedianOfTwoSortedArraysTest](src/test/java/com/thealgorithms/divideandconquer/MedianOfTwoSortedArraysTest.java) + - 📄 [SkylineAlgorithmTest](src/test/java/com/thealgorithms/divideandconquer/SkylineAlgorithmTest.java) + - 📄 [StrassenMatrixMultiplicationTest](src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java) + - 📄 [TilingProblemTest](src/test/java/com/thealgorithms/divideandconquer/TilingProblemTest.java) + - 📁 **dynamicprogramming** + - 📄 [AbbreviationTest](src/test/java/com/thealgorithms/dynamicprogramming/AbbreviationTest.java) + - 📄 [AllConstructTest](src/test/java/com/thealgorithms/dynamicprogramming/AllConstructTest.java) + - 📄 [AssignmentUsingBitmaskTest](src/test/java/com/thealgorithms/dynamicprogramming/AssignmentUsingBitmaskTest.java) + - 📄 [BoardPathTest](src/test/java/com/thealgorithms/dynamicprogramming/BoardPathTest.java) + - 📄 [BoundaryFillTest](src/test/java/com/thealgorithms/dynamicprogramming/BoundaryFillTest.java) + - 📄 [BruteForceKnapsackTest](src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java) + - 📄 [CatalanNumberTest](src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java) + - 📄 [ClimbStairsTest](src/test/java/com/thealgorithms/dynamicprogramming/ClimbStairsTest.java) + - 📄 [CoinChangeTest](src/test/java/com/thealgorithms/dynamicprogramming/CoinChangeTest.java) + - 📄 [CountFriendsPairingTest](src/test/java/com/thealgorithms/dynamicprogramming/CountFriendsPairingTest.java) + - 📄 [DPTest](src/test/java/com/thealgorithms/dynamicprogramming/DPTest.java) + - 📄 [EditDistanceTest](src/test/java/com/thealgorithms/dynamicprogramming/EditDistanceTest.java) + - 📄 [EggDroppingTest](src/test/java/com/thealgorithms/dynamicprogramming/EggDroppingTest.java) + - 📄 [FibonacciTest](src/test/java/com/thealgorithms/dynamicprogramming/FibonacciTest.java) + - 📄 [KadaneAlgorithmTest](src/test/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithmTest.java) + - 📄 [KnapsackMemoizationTest](src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java) + - 📄 [KnapsackTest](src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java) + - 📄 [LevenshteinDistanceTests](src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java) + - 📄 [LongestAlternatingSubsequenceTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequenceTest.java) + - 📄 [LongestArithmeticSubsequenceTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestArithmeticSubsequenceTest.java) + - 📄 [LongestCommonSubsequenceTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequenceTest.java) + - 📄 [LongestIncreasingSubsequenceNLogNTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceNLogNTest.java) + - 📄 [LongestIncreasingSubsequenceTests](src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java) + - 📄 [LongestPalindromicSubstringTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstringTest.java) + - 📄 [LongestValidParenthesesTest](src/test/java/com/thealgorithms/dynamicprogramming/LongestValidParenthesesTest.java) + - 📄 [MatrixChainMultiplicationTest](src/test/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplicationTest.java) + - 📄 [MatrixChainRecursiveTopDownMemoisationTest](src/test/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisationTest.java) + - 📄 [MaximumSumOfNonAdjacentElementsTest](src/test/java/com/thealgorithms/dynamicprogramming/MaximumSumOfNonAdjacentElementsTest.java) + - 📄 [MinimumPathSumTest](src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java) + - 📄 [MinimumSumPartitionTest](src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java) + - 📄 [NewManShanksPrimeTest](src/test/java/com/thealgorithms/dynamicprogramming/NewManShanksPrimeTest.java) + - 📄 [OptimalJobSchedulingTest](src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java) + - 📄 [PalindromicPartitioningTest](src/test/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioningTest.java) + - 📄 [PartitionProblemTest](src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java) + - 📄 [RegexMatchingTest](src/test/java/com/thealgorithms/dynamicprogramming/RegexMatchingTest.java) + - 📄 [RodCuttingTest](src/test/java/com/thealgorithms/dynamicprogramming/RodCuttingTest.java) + - 📄 [ShortestCommonSupersequenceLengthTest](src/test/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLengthTest.java) + - 📄 [SubsetCountTest](src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java) + - 📄 [SubsetSumSpaceOptimizedTest](src/test/java/com/thealgorithms/dynamicprogramming/SubsetSumSpaceOptimizedTest.java) + - 📄 [SubsetSumTest](src/test/java/com/thealgorithms/dynamicprogramming/SubsetSumTest.java) + - 📄 [SumOfSubsetTest](src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java) + - 📄 [TreeMatchingTest](src/test/java/com/thealgorithms/dynamicprogramming/TreeMatchingTest.java) + - 📄 [TribonacciTest](src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java) + - 📄 [UniquePathsTests](src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java) + - 📄 [UniqueSubsequencesCountTest](src/test/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCountTest.java) + - 📄 [WildcardMatchingTest](src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java) + - 📄 [WineProblemTest](src/test/java/com/thealgorithms/dynamicprogramming/WineProblemTest.java) + - 📁 **geometry** + - 📄 [BresenhamLineTest](src/test/java/com/thealgorithms/geometry/BresenhamLineTest.java) + - 📄 [ConvexHullTest](src/test/java/com/thealgorithms/geometry/ConvexHullTest.java) + - 📄 [GrahamScanTest](src/test/java/com/thealgorithms/geometry/GrahamScanTest.java) + - 📄 [MidpointCircleTest](src/test/java/com/thealgorithms/geometry/MidpointCircleTest.java) + - 📄 [MidpointEllipseTest](src/test/java/com/thealgorithms/geometry/MidpointEllipseTest.java) + - 📁 **graph** + - 📄 [ConstrainedShortestPathTest](src/test/java/com/thealgorithms/graph/ConstrainedShortestPathTest.java) + - 📄 [StronglyConnectedComponentOptimizedTest](src/test/java/com/thealgorithms/graph/StronglyConnectedComponentOptimizedTest.java) + - 📄 [TravelingSalesmanTest](src/test/java/com/thealgorithms/graph/TravelingSalesmanTest.java) + - 📁 **greedyalgorithms** + - 📄 [ActivitySelectionTest](src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java) + - 📄 [BandwidthAllocationTest](src/test/java/com/thealgorithms/greedyalgorithms/BandwidthAllocationTest.java) + - 📄 [BinaryAdditionTest](src/test/java/com/thealgorithms/greedyalgorithms/BinaryAdditionTest.java) + - 📄 [CoinChangeTest](src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeTest.java) + - 📄 [DigitSeparationTest](src/test/java/com/thealgorithms/greedyalgorithms/DigitSeparationTest.java) + - 📄 [EgyptianFractionTest](src/test/java/com/thealgorithms/greedyalgorithms/EgyptianFractionTest.java) + - 📄 [FractionalKnapsackTest](src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java) + - 📄 [GaleShapleyTest](src/test/java/com/thealgorithms/greedyalgorithms/GaleShapleyTest.java) + - 📄 [JobSequencingTest](src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java) + - 📄 [KCentersTest](src/test/java/com/thealgorithms/greedyalgorithms/KCentersTest.java) + - 📄 [MergeIntervalsTest](src/test/java/com/thealgorithms/greedyalgorithms/MergeIntervalsTest.java) + - 📄 [MinimizingLatenessTest](src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java) + - 📄 [MinimumWaitingTimeTest](src/test/java/com/thealgorithms/greedyalgorithms/MinimumWaitingTimeTest.java) + - 📄 [OptimalFileMergingTest](src/test/java/com/thealgorithms/greedyalgorithms/OptimalFileMergingTest.java) + - 📄 [StockProfitCalculatorTest](src/test/java/com/thealgorithms/greedyalgorithms/StockProfitCalculatorTest.java) + - 📁 **io** + - 📄 [BufferedReaderTest](src/test/java/com/thealgorithms/io/BufferedReaderTest.java) + - 📁 **lineclipping** + - 📄 [CohenSutherlandTest](src/test/java/com/thealgorithms/lineclipping/CohenSutherlandTest.java) + - 📄 [LiangBarskyTest](src/test/java/com/thealgorithms/lineclipping/LiangBarskyTest.java) + - 📁 **maths** + - 📄 [ADTFractionTest](src/test/java/com/thealgorithms/maths/ADTFractionTest.java) + - 📄 [AbsoluteMaxTest](src/test/java/com/thealgorithms/maths/AbsoluteMaxTest.java) + - 📄 [AbsoluteMinTest](src/test/java/com/thealgorithms/maths/AbsoluteMinTest.java) + - 📄 [AbsoluteValueTest](src/test/java/com/thealgorithms/maths/AbsoluteValueTest.java) + - 📄 [AliquotSumTest](src/test/java/com/thealgorithms/maths/AliquotSumTest.java) + - 📄 [AmicableNumberTest](src/test/java/com/thealgorithms/maths/AmicableNumberTest.java) + - 📄 [AreaTest](src/test/java/com/thealgorithms/maths/AreaTest.java) + - 📄 [ArmstrongTest](src/test/java/com/thealgorithms/maths/ArmstrongTest.java) + - 📄 [AutoCorrelationTest](src/test/java/com/thealgorithms/maths/AutoCorrelationTest.java) + - 📄 [AutomorphicNumberTest](src/test/java/com/thealgorithms/maths/AutomorphicNumberTest.java) + - 📄 [AverageTest](src/test/java/com/thealgorithms/maths/AverageTest.java) + - 📄 [BinaryPowTest](src/test/java/com/thealgorithms/maths/BinaryPowTest.java) + - 📄 [BinomialCoefficientTest](src/test/java/com/thealgorithms/maths/BinomialCoefficientTest.java) + - 📄 [CatalanNumbersTest](src/test/java/com/thealgorithms/maths/CatalanNumbersTest.java) + - 📄 [CeilTest](src/test/java/com/thealgorithms/maths/CeilTest.java) + - 📄 [ChineseRemainderTheoremTest](src/test/java/com/thealgorithms/maths/ChineseRemainderTheoremTest.java) + - 📄 [CollatzConjectureTest](src/test/java/com/thealgorithms/maths/CollatzConjectureTest.java) + - 📄 [CombinationsTest](src/test/java/com/thealgorithms/maths/CombinationsTest.java) + - 📄 [ConvolutionFFTTest](src/test/java/com/thealgorithms/maths/ConvolutionFFTTest.java) + - 📄 [ConvolutionTest](src/test/java/com/thealgorithms/maths/ConvolutionTest.java) + - 📄 [CrossCorrelationTest](src/test/java/com/thealgorithms/maths/CrossCorrelationTest.java) + - 📄 [DeterminantOfMatrixTest](src/test/java/com/thealgorithms/maths/DeterminantOfMatrixTest.java) + - 📄 [DigitalRootTest](src/test/java/com/thealgorithms/maths/DigitalRootTest.java) + - 📄 [DistanceFormulaTest](src/test/java/com/thealgorithms/maths/DistanceFormulaTest.java) + - 📄 [DudeneyNumberTest](src/test/java/com/thealgorithms/maths/DudeneyNumberTest.java) + - 📄 [EulerMethodTest](src/test/java/com/thealgorithms/maths/EulerMethodTest.java) + - 📄 [EulersFunctionTest](src/test/java/com/thealgorithms/maths/EulersFunctionTest.java) + - 📄 [FFTTest](src/test/java/com/thealgorithms/maths/FFTTest.java) + - 📄 [FactorialRecursionTest](src/test/java/com/thealgorithms/maths/FactorialRecursionTest.java) + - 📄 [FactorialTest](src/test/java/com/thealgorithms/maths/FactorialTest.java) + - 📄 [FastExponentiationTest](src/test/java/com/thealgorithms/maths/FastExponentiationTest.java) + - 📄 [FastInverseSqrtTests](src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java) + - 📄 [FibonacciJavaStreamsTest](src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java) + - 📄 [FibonacciLoopTest](src/test/java/com/thealgorithms/maths/FibonacciLoopTest.java) + - 📄 [FibonacciNumberCheckTest](src/test/java/com/thealgorithms/maths/FibonacciNumberCheckTest.java) + - 📄 [FibonacciNumberGoldenRationTest](src/test/java/com/thealgorithms/maths/FibonacciNumberGoldenRationTest.java) + - 📄 [FindKthNumberTest](src/test/java/com/thealgorithms/maths/FindKthNumberTest.java) + - 📄 [FindMaxRecursionTest](src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java) + - 📄 [FindMaxTest](src/test/java/com/thealgorithms/maths/FindMaxTest.java) + - 📄 [FindMinRecursionTest](src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java) + - 📄 [FindMinTest](src/test/java/com/thealgorithms/maths/FindMinTest.java) + - 📄 [FloorTest](src/test/java/com/thealgorithms/maths/FloorTest.java) + - 📄 [FrizzyNumberTest](src/test/java/com/thealgorithms/maths/FrizzyNumberTest.java) + - 📄 [GCDRecursionTest](src/test/java/com/thealgorithms/maths/GCDRecursionTest.java) + - 📄 [GCDTest](src/test/java/com/thealgorithms/maths/GCDTest.java) + - 📄 [GaussianTest](src/test/java/com/thealgorithms/maths/GaussianTest.java) + - 📄 [GenericRootTest](src/test/java/com/thealgorithms/maths/GenericRootTest.java) + - 📄 [GoldbachConjectureTest](src/test/java/com/thealgorithms/maths/GoldbachConjectureTest.java) + - 📄 [HarshadNumberTest](src/test/java/com/thealgorithms/maths/HarshadNumberTest.java) + - 📄 [HeronsFormulaTest](src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java) + - 📄 [JosephusProblemTest](src/test/java/com/thealgorithms/maths/JosephusProblemTest.java) + - 📄 [KaprekarNumbersTest](src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java) + - 📄 [KaratsubaMultiplicationTest](src/test/java/com/thealgorithms/maths/KaratsubaMultiplicationTest.java) + - 📄 [KrishnamurthyNumberTest](src/test/java/com/thealgorithms/maths/KrishnamurthyNumberTest.java) + - 📄 [LeastCommonMultipleTest](src/test/java/com/thealgorithms/maths/LeastCommonMultipleTest.java) + - 📄 [LeonardoNumberTest](src/test/java/com/thealgorithms/maths/LeonardoNumberTest.java) + - 📄 [LongDivisionTest](src/test/java/com/thealgorithms/maths/LongDivisionTest.java) + - 📄 [LucasSeriesTest](src/test/java/com/thealgorithms/maths/LucasSeriesTest.java) + - 📄 [MathBuilderTest](src/test/java/com/thealgorithms/maths/MathBuilderTest.java) + - 📄 [MaxValueTest](src/test/java/com/thealgorithms/maths/MaxValueTest.java) + - 📄 [MeansTest](src/test/java/com/thealgorithms/maths/MeansTest.java) + - 📄 [MedianTest](src/test/java/com/thealgorithms/maths/MedianTest.java) + - 📄 [MinValueTest](src/test/java/com/thealgorithms/maths/MinValueTest.java) + - 📄 [ModeTest](src/test/java/com/thealgorithms/maths/ModeTest.java) + - 📄 [NonRepeatingElementTest](src/test/java/com/thealgorithms/maths/NonRepeatingElementTest.java) + - 📄 [NthUglyNumberTest](src/test/java/com/thealgorithms/maths/NthUglyNumberTest.java) + - 📄 [NumberOfDigitsTest](src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java) + - 📄 [PalindromeNumberTest](src/test/java/com/thealgorithms/maths/PalindromeNumberTest.java) + - 📄 [ParseIntegerTest](src/test/java/com/thealgorithms/maths/ParseIntegerTest.java) + - 📄 [PascalTriangleTest](src/test/java/com/thealgorithms/maths/PascalTriangleTest.java) + - 📄 [PerfectCubeTest](src/test/java/com/thealgorithms/maths/PerfectCubeTest.java) + - 📄 [PerfectNumberTest](src/test/java/com/thealgorithms/maths/PerfectNumberTest.java) + - 📄 [PerfectSquareTest](src/test/java/com/thealgorithms/maths/PerfectSquareTest.java) + - 📄 [PerimeterTest](src/test/java/com/thealgorithms/maths/PerimeterTest.java) + - 📄 [PollardRhoTest](src/test/java/com/thealgorithms/maths/PollardRhoTest.java) + - 📄 [PowTest](src/test/java/com/thealgorithms/maths/PowTest.java) + - 📄 [PowerOfTwoOrNotTest](src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java) + - 📄 [PowerUsingRecursionTest](src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java) + - 📄 [PronicNumberTest](src/test/java/com/thealgorithms/maths/PronicNumberTest.java) + - 📄 [PythagoreanTripleTest](src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java) + - 📄 [QuadraticEquationSolverTest](src/test/java/com/thealgorithms/maths/QuadraticEquationSolverTest.java) + - 📄 [ReverseNumberTest](src/test/java/com/thealgorithms/maths/ReverseNumberTest.java) + - 📄 [SecondMinMaxTest](src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java) + - 📄 [SieveOfEratosthenesTest](src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java) + - 📄 [SolovayStrassenPrimalityTestTest](src/test/java/com/thealgorithms/maths/SolovayStrassenPrimalityTestTest.java) + - 📄 [SquareFreeIntegerTest](src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java) + - 📄 [SquareRootWithNewtonRaphsonTestMethod](src/test/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonTestMethod.java) + - 📄 [SquareRootwithBabylonianMethodTest](src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java) + - 📄 [StandardDeviationTest](src/test/java/com/thealgorithms/maths/StandardDeviationTest.java) + - 📄 [StandardScoreTest](src/test/java/com/thealgorithms/maths/StandardScoreTest.java) + - 📄 [StrobogrammaticNumberTest](src/test/java/com/thealgorithms/maths/StrobogrammaticNumberTest.java) + - 📄 [SumOfArithmeticSeriesTest](src/test/java/com/thealgorithms/maths/SumOfArithmeticSeriesTest.java) + - 📄 [SumOfDigitsTest](src/test/java/com/thealgorithms/maths/SumOfDigitsTest.java) + - 📄 [SumOfOddNumbersTest](src/test/java/com/thealgorithms/maths/SumOfOddNumbersTest.java) + - 📄 [SumWithoutArithmeticOperatorsTest](src/test/java/com/thealgorithms/maths/SumWithoutArithmeticOperatorsTest.java) + - 📄 [TestArmstrong](src/test/java/com/thealgorithms/maths/TestArmstrong.java) + - 📄 [TwinPrimeTest](src/test/java/com/thealgorithms/maths/TwinPrimeTest.java) + - 📄 [UniformNumbersTest](src/test/java/com/thealgorithms/maths/UniformNumbersTest.java) + - 📄 [VampireNumberTest](src/test/java/com/thealgorithms/maths/VampireNumberTest.java) + - 📄 [VolumeTest](src/test/java/com/thealgorithms/maths/VolumeTest.java) + - 📁 **prime** + - 📄 [LiouvilleLambdaFunctionTest](src/test/java/com/thealgorithms/maths/prime/LiouvilleLambdaFunctionTest.java) + - 📄 [MillerRabinPrimalityCheckTest](src/test/java/com/thealgorithms/maths/prime/MillerRabinPrimalityCheckTest.java) + - 📄 [MobiusFunctionTest](src/test/java/com/thealgorithms/maths/prime/MobiusFunctionTest.java) + - 📄 [PrimeCheckTest](src/test/java/com/thealgorithms/maths/prime/PrimeCheckTest.java) + - 📄 [PrimeFactorizationTest](src/test/java/com/thealgorithms/maths/prime/PrimeFactorizationTest.java) + - 📁 **matrix** + - 📄 [InverseOfMatrixTest](src/test/java/com/thealgorithms/matrix/InverseOfMatrixTest.java) + - 📄 [MatrixRankTest](src/test/java/com/thealgorithms/matrix/MatrixRankTest.java) + - 📄 [MatrixTransposeTest](src/test/java/com/thealgorithms/matrix/MatrixTransposeTest.java) + - 📄 [MatrixUtilTest](src/test/java/com/thealgorithms/matrix/MatrixUtilTest.java) + - 📄 [MedianOfMatrixTest](src/test/java/com/thealgorithms/matrix/MedianOfMatrixTest.java) + - 📄 [MirrorOfMatrixTest](src/test/java/com/thealgorithms/matrix/MirrorOfMatrixTest.java) + - 📄 [SolveSystemTest](src/test/java/com/thealgorithms/matrix/SolveSystemTest.java) + - 📄 [TestPrintMatrixInSpiralOrder](src/test/java/com/thealgorithms/matrix/TestPrintMatrixInSpiralOrder.java) + - 📁 **misc** + - 📄 [ColorContrastRatioTest](src/test/java/com/thealgorithms/misc/ColorContrastRatioTest.java) + - 📄 [MapReduceTest](src/test/java/com/thealgorithms/misc/MapReduceTest.java) + - 📄 [MedianOfRunningArrayTest](src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java) + - 📄 [PalindromePrimeTest](src/test/java/com/thealgorithms/misc/PalindromePrimeTest.java) + - 📄 [PalindromeSinglyLinkedListTest](src/test/java/com/thealgorithms/misc/PalindromeSinglyLinkedListTest.java) + - 📄 [RangeInSortedArrayTest](src/test/java/com/thealgorithms/misc/RangeInSortedArrayTest.java) + - 📄 [ShuffleArrayTest](src/test/java/com/thealgorithms/misc/ShuffleArrayTest.java) + - 📄 [SparsityTest](src/test/java/com/thealgorithms/misc/SparsityTest.java) + - 📄 [ThreeSumProblemTest](src/test/java/com/thealgorithms/misc/ThreeSumProblemTest.java) + - 📄 [TwoSumProblemTest](src/test/java/com/thealgorithms/misc/TwoSumProblemTest.java) + - 📁 **others** + - 📄 [ArrayLeftRotationTest](src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java) + - 📄 [ArrayRightRotationTest](src/test/java/com/thealgorithms/others/ArrayRightRotationTest.java) + - 📄 [BFPRTTest](src/test/java/com/thealgorithms/others/BFPRTTest.java) + - 📄 [BestFitCPUTest](src/test/java/com/thealgorithms/others/BestFitCPUTest.java) + - 📄 [BoyerMooreTest](src/test/java/com/thealgorithms/others/BoyerMooreTest.java) + - 📄 [CRC16Test](src/test/java/com/thealgorithms/others/CRC16Test.java) + - 📄 [CRCAlgorithmTest](src/test/java/com/thealgorithms/others/CRCAlgorithmTest.java) + - 📄 [ConwayTest](src/test/java/com/thealgorithms/others/ConwayTest.java) + - 📄 [CountFriendsPairingTest](src/test/java/com/thealgorithms/others/CountFriendsPairingTest.java) + - 📄 [FirstFitCPUTest](src/test/java/com/thealgorithms/others/FirstFitCPUTest.java) + - 📄 [FloydTriangleTest](src/test/java/com/thealgorithms/others/FloydTriangleTest.java) + - 📄 [KadaneAlogrithmTest](src/test/java/com/thealgorithms/others/KadaneAlogrithmTest.java) + - 📄 [LineSweepTest](src/test/java/com/thealgorithms/others/LineSweepTest.java) + - 📄 [LinkListSortTest](src/test/java/com/thealgorithms/others/LinkListSortTest.java) + - 📄 [LowestBasePalindromeTest](src/test/java/com/thealgorithms/others/LowestBasePalindromeTest.java) + - 📄 [MaximumSlidingWindowTest](src/test/java/com/thealgorithms/others/MaximumSlidingWindowTest.java) + - 📄 [MaximumSumOfDistinctSubarraysWithLengthKTest](src/test/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthKTest.java) + - 📄 [NewManShanksPrimeTest](src/test/java/com/thealgorithms/others/NewManShanksPrimeTest.java) + - 📄 [NextFitTest](src/test/java/com/thealgorithms/others/NextFitTest.java) + - 📄 [PasswordGenTest](src/test/java/com/thealgorithms/others/PasswordGenTest.java) + - 📄 [QueueUsingTwoStacksTest](src/test/java/com/thealgorithms/others/QueueUsingTwoStacksTest.java) + - 📄 [RemoveDuplicateFromStringTest](src/test/java/com/thealgorithms/others/RemoveDuplicateFromStringTest.java) + - 📄 [ReverseStackUsingRecursionTest](src/test/java/com/thealgorithms/others/ReverseStackUsingRecursionTest.java) + - 📄 [SkylineProblemTest](src/test/java/com/thealgorithms/others/SkylineProblemTest.java) + - 📄 [TestPrintMatrixInSpiralOrder](src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java) + - 📄 [TwoPointersTest](src/test/java/com/thealgorithms/others/TwoPointersTest.java) + - 📄 [WorstFitCPUTest](src/test/java/com/thealgorithms/others/WorstFitCPUTest.java) + - 📁 **cn** + - 📄 [HammingDistanceTest](src/test/java/com/thealgorithms/others/cn/HammingDistanceTest.java) + - 📁 **puzzlesandgames** + - 📄 [SudokuTest](src/test/java/com/thealgorithms/puzzlesandgames/SudokuTest.java) + - 📄 [TowerOfHanoiTest](src/test/java/com/thealgorithms/puzzlesandgames/TowerOfHanoiTest.java) + - 📄 [WordBoggleTest](src/test/java/com/thealgorithms/puzzlesandgames/WordBoggleTest.java) + - 📁 **randomized** + - 📄 [KargerMinCutTest](src/test/java/com/thealgorithms/randomized/KargerMinCutTest.java) + - 📄 [MonteCarloIntegrationTest](src/test/java/com/thealgorithms/randomized/MonteCarloIntegrationTest.java) + - 📄 [RandomizedQuickSortTest](src/test/java/com/thealgorithms/randomized/RandomizedQuickSortTest.java) + - 📄 [ReservoirSamplingTest](src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java) + - 📁 **recursion** + - 📄 [FibonacciSeriesTest](src/test/java/com/thealgorithms/recursion/FibonacciSeriesTest.java) + - 📄 [GenerateSubsetsTest](src/test/java/com/thealgorithms/recursion/GenerateSubsetsTest.java) + - 📁 **scheduling** + - 📄 [AgingSchedulingTest](src/test/java/com/thealgorithms/scheduling/AgingSchedulingTest.java) + - 📄 [EDFSchedulingTest](src/test/java/com/thealgorithms/scheduling/EDFSchedulingTest.java) + - 📄 [FCFSSchedulingTest](src/test/java/com/thealgorithms/scheduling/FCFSSchedulingTest.java) + - 📄 [FairShareSchedulingTest](src/test/java/com/thealgorithms/scheduling/FairShareSchedulingTest.java) + - 📄 [GangSchedulingTest](src/test/java/com/thealgorithms/scheduling/GangSchedulingTest.java) + - 📄 [HighestResponseRatioNextSchedulingTest](src/test/java/com/thealgorithms/scheduling/HighestResponseRatioNextSchedulingTest.java) + - 📄 [JobSchedulingWithDeadlineTest](src/test/java/com/thealgorithms/scheduling/JobSchedulingWithDeadlineTest.java) + - 📄 [LotterySchedulingTest](src/test/java/com/thealgorithms/scheduling/LotterySchedulingTest.java) + - 📄 [MLFQSchedulerTest](src/test/java/com/thealgorithms/scheduling/MLFQSchedulerTest.java) + - 📄 [MultiAgentSchedulingTest](src/test/java/com/thealgorithms/scheduling/MultiAgentSchedulingTest.java) + - 📄 [NonPreemptivePrioritySchedulingTest](src/test/java/com/thealgorithms/scheduling/NonPreemptivePrioritySchedulingTest.java) + - 📄 [PreemptivePrioritySchedulingTest](src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java) + - 📄 [ProportionalFairSchedulingTest](src/test/java/com/thealgorithms/scheduling/ProportionalFairSchedulingTest.java) + - 📄 [RRSchedulingTest](src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java) + - 📄 [RandomSchedulingTest](src/test/java/com/thealgorithms/scheduling/RandomSchedulingTest.java) + - 📄 [SJFSchedulingTest](src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java) + - 📄 [SRTFSchedulingTest](src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java) + - 📄 [SelfAdjustingSchedulingTest](src/test/java/com/thealgorithms/scheduling/SelfAdjustingSchedulingTest.java) + - 📄 [SlackTimeSchedulingTest](src/test/java/com/thealgorithms/scheduling/SlackTimeSchedulingTest.java) + - 📁 **diskscheduling** + - 📄 [CircularLookSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/CircularLookSchedulingTest.java) + - 📄 [CircularScanSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/CircularScanSchedulingTest.java) + - 📄 [LookSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/LookSchedulingTest.java) + - 📄 [SSFSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/SSFSchedulingTest.java) + - 📄 [ScanSchedulingTest](src/test/java/com/thealgorithms/scheduling/diskscheduling/ScanSchedulingTest.java) + - 📁 **searches** + - 📄 [BM25InvertedIndexTest](src/test/java/com/thealgorithms/searches/BM25InvertedIndexTest.java) + - 📄 [BinarySearch2dArrayTest](src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java) + - 📄 [BinarySearchTest](src/test/java/com/thealgorithms/searches/BinarySearchTest.java) + - 📄 [BoyerMooreTest](src/test/java/com/thealgorithms/searches/BoyerMooreTest.java) + - 📄 [BreadthFirstSearchTest](src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java) + - 📄 [DepthFirstSearchTest](src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java) + - 📄 [ExponentialSearchTest](src/test/java/com/thealgorithms/searches/ExponentialSearchTest.java) + - 📄 [FibonacciSearchTest](src/test/java/com/thealgorithms/searches/FibonacciSearchTest.java) + - 📄 [HowManyTimesRotatedTest](src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java) + - 📄 [InterpolationSearchTest](src/test/java/com/thealgorithms/searches/InterpolationSearchTest.java) + - 📄 [IterativeBinarySearchTest](src/test/java/com/thealgorithms/searches/IterativeBinarySearchTest.java) + - 📄 [IterativeTernarySearchTest](src/test/java/com/thealgorithms/searches/IterativeTernarySearchTest.java) + - 📄 [JumpSearchTest](src/test/java/com/thealgorithms/searches/JumpSearchTest.java) + - 📄 [KMPSearchTest](src/test/java/com/thealgorithms/searches/KMPSearchTest.java) + - 📄 [LinearSearchTest](src/test/java/com/thealgorithms/searches/LinearSearchTest.java) + - 📄 [LinearSearchThreadTest](src/test/java/com/thealgorithms/searches/LinearSearchThreadTest.java) + - 📄 [LowerBoundTest](src/test/java/com/thealgorithms/searches/LowerBoundTest.java) + - 📄 [MonteCarloTreeSearchTest](src/test/java/com/thealgorithms/searches/MonteCarloTreeSearchTest.java) + - 📄 [OrderAgnosticBinarySearchTest](src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java) + - 📄 [PerfectBinarySearchTest](src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java) + - 📄 [QuickSelectTest](src/test/java/com/thealgorithms/searches/QuickSelectTest.java) + - 📄 [RabinKarpAlgorithmTest](src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java) + - 📄 [RandomSearchTest](src/test/java/com/thealgorithms/searches/RandomSearchTest.java) + - 📄 [RecursiveBinarySearchTest](src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java) + - 📄 [RowColumnWiseSorted2dArrayBinarySearchTest](src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java) + - 📄 [SaddlebackSearchTest](src/test/java/com/thealgorithms/searches/SaddlebackSearchTest.java) + - 📄 [SearchInARowAndColWiseSortedMatrixTest](src/test/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrixTest.java) + - 📄 [SortOrderAgnosticBinarySearchTest](src/test/java/com/thealgorithms/searches/SortOrderAgnosticBinarySearchTest.java) + - 📄 [SquareRootBinarySearchTest](src/test/java/com/thealgorithms/searches/SquareRootBinarySearchTest.java) + - 📄 [TernarySearchTest](src/test/java/com/thealgorithms/searches/TernarySearchTest.java) + - 📄 [TestSearchInARowAndColWiseSortedMatrix](src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java) + - 📄 [UnionFindTest](src/test/java/com/thealgorithms/searches/UnionFindTest.java) + - 📄 [UpperBoundTest](src/test/java/com/thealgorithms/searches/UpperBoundTest.java) + - 📁 **slidingwindow** + - 📄 [LongestSubarrayWithSumLessOrEqualToKTest](src/test/java/com/thealgorithms/slidingwindow/LongestSubarrayWithSumLessOrEqualToKTest.java) + - 📄 [LongestSubstringWithoutRepeatingCharactersTest](src/test/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharactersTest.java) + - 📄 [MaxSumKSizeSubarrayTest](src/test/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarrayTest.java) + - 📄 [MinSumKSizeSubarrayTest](src/test/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarrayTest.java) + - 📄 [ShortestCoprimeSegmentTest](src/test/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegmentTest.java) + - 📁 **sorts** + - 📄 [AdaptiveMergeSortTest](src/test/java/com/thealgorithms/sorts/AdaptiveMergeSortTest.java) + - 📄 [BeadSortTest](src/test/java/com/thealgorithms/sorts/BeadSortTest.java) + - 📄 [BinaryInsertionSortTest](src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java) + - 📄 [BitonicSortTest](src/test/java/com/thealgorithms/sorts/BitonicSortTest.java) + - 📄 [BogoSortTest](src/test/java/com/thealgorithms/sorts/BogoSortTest.java) + - 📄 [BubbleSortRecursiveTest](src/test/java/com/thealgorithms/sorts/BubbleSortRecursiveTest.java) + - 📄 [BubbleSortTest](src/test/java/com/thealgorithms/sorts/BubbleSortTest.java) + - 📄 [BucketSortTest](src/test/java/com/thealgorithms/sorts/BucketSortTest.java) + - 📄 [CircleSortTest](src/test/java/com/thealgorithms/sorts/CircleSortTest.java) + - 📄 [CocktailShakerSortTest](src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.java) + - 📄 [CombSortTest](src/test/java/com/thealgorithms/sorts/CombSortTest.java) + - 📄 [CountingSortTest](src/test/java/com/thealgorithms/sorts/CountingSortTest.java) + - 📄 [CycleSortTest](src/test/java/com/thealgorithms/sorts/CycleSortTest.java) + - 📄 [DarkSortTest](src/test/java/com/thealgorithms/sorts/DarkSortTest.java) + - 📄 [DualPivotQuickSortTest](src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java) + - 📄 [DutchNationalFlagSortTest](src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java) + - 📄 [ExchangeSortTest](src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java) + - 📄 [FlashSortTest](src/test/java/com/thealgorithms/sorts/FlashSortTest.java) + - 📄 [GnomeSortTest](src/test/java/com/thealgorithms/sorts/GnomeSortTest.java) + - 📄 [HeapSortTest](src/test/java/com/thealgorithms/sorts/HeapSortTest.java) + - 📄 [InsertionSortTest](src/test/java/com/thealgorithms/sorts/InsertionSortTest.java) + - 📄 [IntrospectiveSortTest](src/test/java/com/thealgorithms/sorts/IntrospectiveSortTest.java) + - 📄 [MergeSortNoExtraSpaceTest](src/test/java/com/thealgorithms/sorts/MergeSortNoExtraSpaceTest.java) + - 📄 [MergeSortRecursiveTest](src/test/java/com/thealgorithms/sorts/MergeSortRecursiveTest.java) + - 📄 [MergeSortTest](src/test/java/com/thealgorithms/sorts/MergeSortTest.java) + - 📄 [OddEvenSortTest](src/test/java/com/thealgorithms/sorts/OddEvenSortTest.java) + - 📄 [PancakeSortTest](src/test/java/com/thealgorithms/sorts/PancakeSortTest.java) + - 📄 [PatienceSortTest](src/test/java/com/thealgorithms/sorts/PatienceSortTest.java) + - 📄 [PigeonholeSortTest](src/test/java/com/thealgorithms/sorts/PigeonholeSortTest.java) + - 📄 [QuickSortTest](src/test/java/com/thealgorithms/sorts/QuickSortTest.java) + - 📄 [RadixSortTest](src/test/java/com/thealgorithms/sorts/RadixSortTest.java) + - 📄 [SelectionSortRecursiveTest](src/test/java/com/thealgorithms/sorts/SelectionSortRecursiveTest.java) + - 📄 [SelectionSortTest](src/test/java/com/thealgorithms/sorts/SelectionSortTest.java) + - 📄 [ShellSortTest](src/test/java/com/thealgorithms/sorts/ShellSortTest.java) + - 📄 [SimpleSortTest](src/test/java/com/thealgorithms/sorts/SimpleSortTest.java) + - 📄 [SlowSortTest](src/test/java/com/thealgorithms/sorts/SlowSortTest.java) + - 📄 [SortUtilsRandomGeneratorTest](src/test/java/com/thealgorithms/sorts/SortUtilsRandomGeneratorTest.java) + - 📄 [SortUtilsTest](src/test/java/com/thealgorithms/sorts/SortUtilsTest.java) + - 📄 [SortingAlgorithmTest](src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java) + - 📄 [SpreadSortTest](src/test/java/com/thealgorithms/sorts/SpreadSortTest.java) + - 📄 [StalinSortTest](src/test/java/com/thealgorithms/sorts/StalinSortTest.java) + - 📄 [StoogeSortTest](src/test/java/com/thealgorithms/sorts/StoogeSortTest.java) + - 📄 [StrandSortTest](src/test/java/com/thealgorithms/sorts/StrandSortTest.java) + - 📄 [SwapSortTest](src/test/java/com/thealgorithms/sorts/SwapSortTest.java) + - 📄 [TimSortTest](src/test/java/com/thealgorithms/sorts/TimSortTest.java) + - 📄 [TopologicalSortTest](src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java) + - 📄 [TreeSortTest](src/test/java/com/thealgorithms/sorts/TreeSortTest.java) + - 📄 [WaveSortTest](src/test/java/com/thealgorithms/sorts/WaveSortTest.java) + - 📄 [WiggleSortTest](src/test/java/com/thealgorithms/sorts/WiggleSortTest.java) + - 📁 **stacks** + - 📄 [BalancedBracketsTest](src/test/java/com/thealgorithms/stacks/BalancedBracketsTest.java) + - 📄 [CelebrityFinderTest](src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java) + - 📄 [DecimalToAnyUsingStackTest](src/test/java/com/thealgorithms/stacks/DecimalToAnyUsingStackTest.java) + - 📄 [DuplicateBracketsTest](src/test/java/com/thealgorithms/stacks/DuplicateBracketsTest.java) + - 📄 [GreatestElementConstantTimeTest](src/test/java/com/thealgorithms/stacks/GreatestElementConstantTimeTest.java) + - 📄 [InfixToPostfixTest](src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java) + - 📄 [InfixToPrefixTest](src/test/java/com/thealgorithms/stacks/InfixToPrefixTest.java) + - 📄 [LargestRectangleTest](src/test/java/com/thealgorithms/stacks/LargestRectangleTest.java) + - 📄 [MinStackUsingSingleStackTest](src/test/java/com/thealgorithms/stacks/MinStackUsingSingleStackTest.java) + - 📄 [MinStackUsingTwoStacksTest](src/test/java/com/thealgorithms/stacks/MinStackUsingTwoStacksTest.java) + - 📄 [NextGreaterElementTest](src/test/java/com/thealgorithms/stacks/NextGreaterElementTest.java) + - 📄 [NextSmallerElementTest](src/test/java/com/thealgorithms/stacks/NextSmallerElementTest.java) + - 📄 [PalindromeWithStackTest](src/test/java/com/thealgorithms/stacks/PalindromeWithStackTest.java) + - 📄 [PostfixEvaluatorTest](src/test/java/com/thealgorithms/stacks/PostfixEvaluatorTest.java) + - 📄 [PostfixToInfixTest](src/test/java/com/thealgorithms/stacks/PostfixToInfixTest.java) + - 📄 [PrefixEvaluatorTest](src/test/java/com/thealgorithms/stacks/PrefixEvaluatorTest.java) + - 📄 [PrefixToInfixTest](src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java) + - 📄 [SmallestElementConstantTimeTest](src/test/java/com/thealgorithms/stacks/SmallestElementConstantTimeTest.java) + - 📄 [SortStackTest](src/test/java/com/thealgorithms/stacks/SortStackTest.java) + - 📄 [StackPostfixNotationTest](src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java) + - 📄 [StackUsingTwoQueuesTest](src/test/java/com/thealgorithms/stacks/StackUsingTwoQueuesTest.java) + - 📁 **strings** + - 📄 [AhoCorasickTest](src/test/java/com/thealgorithms/strings/AhoCorasickTest.java) + - 📄 [AlphabeticalTest](src/test/java/com/thealgorithms/strings/AlphabeticalTest.java) + - 📄 [AnagramsTest](src/test/java/com/thealgorithms/strings/AnagramsTest.java) + - 📄 [CharactersSameTest](src/test/java/com/thealgorithms/strings/CharactersSameTest.java) + - 📄 [CheckVowelsTest](src/test/java/com/thealgorithms/strings/CheckVowelsTest.java) + - 📄 [CountCharTest](src/test/java/com/thealgorithms/strings/CountCharTest.java) + - 📄 [CountWordsTest](src/test/java/com/thealgorithms/strings/CountWordsTest.java) + - 📄 [HammingDistanceTest](src/test/java/com/thealgorithms/strings/HammingDistanceTest.java) + - 📄 [HorspoolSearchTest](src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java) + - 📄 [IsomorphicTest](src/test/java/com/thealgorithms/strings/IsomorphicTest.java) + - 📄 [LetterCombinationsOfPhoneNumberTest](src/test/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumberTest.java) + - 📄 [LongestCommonPrefixTest](src/test/java/com/thealgorithms/strings/LongestCommonPrefixTest.java) + - 📄 [LongestNonRepetitiveSubstringTest](src/test/java/com/thealgorithms/strings/LongestNonRepetitiveSubstringTest.java) + - 📄 [LongestPalindromicSubstringTest](src/test/java/com/thealgorithms/strings/LongestPalindromicSubstringTest.java) + - 📄 [LowerTest](src/test/java/com/thealgorithms/strings/LowerTest.java) + - 📄 [ManacherTest](src/test/java/com/thealgorithms/strings/ManacherTest.java) + - 📄 [MyAtoiTest](src/test/java/com/thealgorithms/strings/MyAtoiTest.java) + - 📄 [PalindromeTest](src/test/java/com/thealgorithms/strings/PalindromeTest.java) + - 📄 [PangramTest](src/test/java/com/thealgorithms/strings/PangramTest.java) + - 📄 [PermuteStringTest](src/test/java/com/thealgorithms/strings/PermuteStringTest.java) + - 📄 [ReturnSubsequenceTest](src/test/java/com/thealgorithms/strings/ReturnSubsequenceTest.java) + - 📄 [ReverseStringRecursiveTest](src/test/java/com/thealgorithms/strings/ReverseStringRecursiveTest.java) + - 📄 [ReverseStringTest](src/test/java/com/thealgorithms/strings/ReverseStringTest.java) + - 📄 [ReverseWordsInStringTest](src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java) + - 📄 [RotationTest](src/test/java/com/thealgorithms/strings/RotationTest.java) + - 📄 [StringCompressionTest](src/test/java/com/thealgorithms/strings/StringCompressionTest.java) + - 📄 [StringMatchFiniteAutomataTest](src/test/java/com/thealgorithms/strings/StringMatchFiniteAutomataTest.java) + - 📄 [UpperTest](src/test/java/com/thealgorithms/strings/UpperTest.java) + - 📄 [ValidParenthesesTest](src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java) + - 📄 [WordLadderTest](src/test/java/com/thealgorithms/strings/WordLadderTest.java) + - 📁 **zigZagPattern** + - 📄 [ZigZagPatternTest](src/test/java/com/thealgorithms/strings/zigZagPattern/ZigZagPatternTest.java) + - 📁 **tree** + - 📄 [HeavyLightDecompositionTest](src/test/java/com/thealgorithms/tree/HeavyLightDecompositionTest.java) \ No newline at end of file From bb36d13c93cc2c3684e92eb5c78b79860e010179 Mon Sep 17 00:00:00 2001 From: KevinMwita7 Date: Mon, 30 Jun 2025 21:45:37 +0300 Subject: [PATCH 113/146] Add RR cache (#6307) --- .../datastructures/caches/RRCache.java | 505 ++++++++++++++++++ .../datastructures/caches/RRCacheTest.java | 222 ++++++++ 2 files changed, 727 insertions(+) create mode 100644 src/main/java/com/thealgorithms/datastructures/caches/RRCache.java create mode 100644 src/test/java/com/thealgorithms/datastructures/caches/RRCacheTest.java diff --git a/src/main/java/com/thealgorithms/datastructures/caches/RRCache.java b/src/main/java/com/thealgorithms/datastructures/caches/RRCache.java new file mode 100644 index 000000000000..1821872be9cd --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/caches/RRCache.java @@ -0,0 +1,505 @@ +package com.thealgorithms.datastructures.caches; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.BiConsumer; + +/** + * A thread-safe generic cache implementation using the Random Replacement (RR) eviction policy. + *

+ * The cache holds a fixed number of entries, defined by its capacity. When the cache is full and a + * new entry is added, one of the existing entries is selected at random and evicted to make space. + *

+ * Optionally, entries can have a time-to-live (TTL) in milliseconds. If a TTL is set, entries will + * automatically expire and be removed upon access or insertion attempts. + *

+ * Features: + *

    + *
  • Random eviction when capacity is exceeded
  • + *
  • Optional TTL (time-to-live in milliseconds) per entry or default TTL for all entries
  • + *
  • Thread-safe access using locking
  • + *
  • Hit and miss counters for cache statistics
  • + *
  • Eviction listener callback support
  • + *
+ * + * @param the type of keys maintained by this cache + * @param the type of mapped values + * See Random Replacement + * @author Kevin Babu (GitHub) + */ +public final class RRCache { + + private final int capacity; + private final long defaultTTL; + private final Map> cache; + private final List keys; + private final Random random; + private final Lock lock; + + private long hits = 0; + private long misses = 0; + private final BiConsumer evictionListener; + private final EvictionStrategy evictionStrategy; + + /** + * Internal structure to store value + expiry timestamp. + * + * @param the type of the value being cached + */ + private static class CacheEntry { + V value; + long expiryTime; + + /** + * Constructs a new {@code CacheEntry} with the specified value and time-to-live (TTL). + * + * @param value the value to cache + * @param ttlMillis the time-to-live in milliseconds + */ + CacheEntry(V value, long ttlMillis) { + this.value = value; + this.expiryTime = System.currentTimeMillis() + ttlMillis; + } + + /** + * Checks if the cache entry has expired. + * + * @return {@code true} if the current time is past the expiration time; {@code false} otherwise + */ + boolean isExpired() { + return System.currentTimeMillis() > expiryTime; + } + } + + /** + * Constructs a new {@code RRCache} instance using the provided {@link Builder}. + * + *

This constructor initializes the cache with the specified capacity and default TTL, + * sets up internal data structures (a {@code HashMap} for cache entries and an {@code ArrayList} + * for key tracking), and configures eviction and randomization behavior. + * + * @param builder the {@code Builder} object containing configuration parameters + */ + private RRCache(Builder builder) { + this.capacity = builder.capacity; + this.defaultTTL = builder.defaultTTL; + this.cache = new HashMap<>(builder.capacity); + this.keys = new ArrayList<>(builder.capacity); + this.random = builder.random != null ? builder.random : new Random(); + this.lock = new ReentrantLock(); + this.evictionListener = builder.evictionListener; + this.evictionStrategy = builder.evictionStrategy; + } + + /** + * Retrieves the value associated with the specified key from the cache. + * + *

If the key is not present or the corresponding entry has expired, this method + * returns {@code null}. If an expired entry is found, it will be removed and the + * eviction listener (if any) will be notified. Cache hit-and-miss statistics are + * also updated accordingly. + * + * @param key the key whose associated value is to be returned; must not be {@code null} + * @return the cached value associated with the key, or {@code null} if not present or expired + * @throws IllegalArgumentException if {@code key} is {@code null} + */ + public V get(K key) { + if (key == null) { + throw new IllegalArgumentException("Key must not be null"); + } + + lock.lock(); + try { + evictionStrategy.onAccess(this); + + CacheEntry entry = cache.get(key); + if (entry == null || entry.isExpired()) { + if (entry != null) { + removeKey(key); + notifyEviction(key, entry.value); + } + misses++; + return null; + } + hits++; + return entry.value; + } finally { + lock.unlock(); + } + } + + /** + * Adds a key-value pair to the cache using the default time-to-live (TTL). + * + *

The key may overwrite an existing entry. The actual insertion is delegated + * to the overloaded {@link #put(K, V, long)} method. + * + * @param key the key to cache the value under + * @param value the value to be cached + */ + public void put(K key, V value) { + put(key, value, defaultTTL); + } + + /** + * Adds a key-value pair to the cache with a specified time-to-live (TTL). + * + *

If the key already exists, its value is updated and its TTL is reset. If the key + * does not exist and the cache is full, a random entry is evicted to make space. + * Expired entries are also cleaned up prior to any eviction. The eviction listener + * is notified when an entry gets evicted. + * + * @param key the key to associate with the cached value; must not be {@code null} + * @param value the value to be cached; must not be {@code null} + * @param ttlMillis the time-to-live for this entry in milliseconds; must be >= 0 + * @throws IllegalArgumentException if {@code key} or {@code value} is {@code null}, or if {@code ttlMillis} is negative + */ + public void put(K key, V value, long ttlMillis) { + if (key == null || value == null) { + throw new IllegalArgumentException("Key and value must not be null"); + } + if (ttlMillis < 0) { + throw new IllegalArgumentException("TTL must be >= 0"); + } + + lock.lock(); + try { + if (cache.containsKey(key)) { + cache.put(key, new CacheEntry<>(value, ttlMillis)); + return; + } + + evictExpired(); + + if (cache.size() >= capacity) { + int idx = random.nextInt(keys.size()); + K evictKey = keys.remove(idx); + CacheEntry evictVal = cache.remove(evictKey); + notifyEviction(evictKey, evictVal.value); + } + + cache.put(key, new CacheEntry<>(value, ttlMillis)); + keys.add(key); + } finally { + lock.unlock(); + } + } + + /** + * Removes all expired entries from the cache. + * + *

This method iterates through the list of cached keys and checks each associated + * entry for expiration. Expired entries are removed from both the key tracking list + * and the cache map. For each eviction, the eviction listener is notified. + */ + private int evictExpired() { + Iterator it = keys.iterator(); + int expiredCount = 0; + + while (it.hasNext()) { + K k = it.next(); + CacheEntry entry = cache.get(k); + if (entry != null && entry.isExpired()) { + it.remove(); + cache.remove(k); + ++expiredCount; + notifyEviction(k, entry.value); + } + } + return expiredCount; + } + + /** + * Removes the specified key and its associated entry from the cache. + * + *

This method deletes the key from both the cache map and the key tracking list. + * + * @param key the key to remove from the cache + */ + private void removeKey(K key) { + cache.remove(key); + keys.remove(key); + } + + /** + * Notifies the eviction listener, if one is registered, that a key-value pair has been evicted. + * + *

If the {@code evictionListener} is not {@code null}, it is invoked with the provided key + * and value. Any exceptions thrown by the listener are caught and logged to standard error, + * preventing them from disrupting cache operations. + * + * @param key the key that was evicted + * @param value the value that was associated with the evicted key + */ + private void notifyEviction(K key, V value) { + if (evictionListener != null) { + try { + evictionListener.accept(key, value); + } catch (Exception e) { + System.err.println("Eviction listener failed: " + e.getMessage()); + } + } + } + + /** + * Returns the number of successful cache lookups (hits). + * + * @return the number of cache hits + */ + public long getHits() { + lock.lock(); + try { + return hits; + } finally { + lock.unlock(); + } + } + + /** + * Returns the number of failed cache lookups (misses), including expired entries. + * + * @return the number of cache misses + */ + public long getMisses() { + lock.lock(); + try { + return misses; + } finally { + lock.unlock(); + } + } + + /** + * Returns the current number of entries in the cache, excluding expired ones. + * + * @return the current cache size + */ + public int size() { + lock.lock(); + try { + int cachedSize = cache.size(); + int evictedCount = evictionStrategy.onAccess(this); + if (evictedCount > 0) { + return cachedSize - evictedCount; + } + + // This runs if periodic eviction does not occur + int count = 0; + for (Map.Entry> entry : cache.entrySet()) { + if (!entry.getValue().isExpired()) { + ++count; + } + } + return count; + } finally { + lock.unlock(); + } + } + + /** + * Returns the current {@link EvictionStrategy} used by this cache instance. + + * @return the eviction strategy currently assigned to this cache + */ + public EvictionStrategy getEvictionStrategy() { + return evictionStrategy; + } + + /** + * Returns a string representation of the cache, including metadata and current non-expired entries. + * + *

The returned string includes the cache's capacity, current size (excluding expired entries), + * hit-and-miss counts, and a map of all non-expired key-value pairs. This method acquires a lock + * to ensure thread-safe access. + * + * @return a string summarizing the state of the cache + */ + @Override + public String toString() { + lock.lock(); + try { + Map visible = new HashMap<>(); + for (Map.Entry> entry : cache.entrySet()) { + if (!entry.getValue().isExpired()) { + visible.put(entry.getKey(), entry.getValue().value); + } + } + return String.format("Cache(capacity=%d, size=%d, hits=%d, misses=%d, entries=%s)", capacity, visible.size(), hits, misses, visible); + } finally { + lock.unlock(); + } + } + + /** + * A strategy interface for controlling when expired entries are evicted from the cache. + * + *

Implementations decide whether and when to trigger {@link RRCache#evictExpired()} based + * on cache usage patterns. This allows for flexible eviction behaviour such as periodic cleanup, + * or no automatic cleanup. + * + * @param the type of keys maintained by the cache + * @param the type of cached values + */ + public interface EvictionStrategy { + /** + * Called on each cache access (e.g., {@link RRCache#get(Object)}) to optionally trigger eviction. + * + * @param cache the cache instance on which this strategy is applied + * @return the number of expired entries evicted during this access + */ + int onAccess(RRCache cache); + } + + /** + * An eviction strategy that performs eviction of expired entries on each call. + * + * @param the type of keys + * @param the type of values + */ + public static class NoEvictionStrategy implements EvictionStrategy { + @Override + public int onAccess(RRCache cache) { + return cache.evictExpired(); + } + } + + /** + * An eviction strategy that triggers eviction every fixed number of accesses. + * + *

This deterministic strategy ensures cleanup occurs at predictable intervals, + * ideal for moderately active caches where memory usage is a concern. + * + * @param the type of keys + * @param the type of values + */ + public static class PeriodicEvictionStrategy implements EvictionStrategy { + private final int interval; + private int counter = 0; + + /** + * Constructs a periodic eviction strategy. + * + * @param interval the number of accesses between evictions; must be > 0 + * @throws IllegalArgumentException if {@code interval} is less than or equal to 0 + */ + public PeriodicEvictionStrategy(int interval) { + if (interval <= 0) { + throw new IllegalArgumentException("Interval must be > 0"); + } + this.interval = interval; + } + + @Override + public int onAccess(RRCache cache) { + if (++counter % interval == 0) { + return cache.evictExpired(); + } + + return 0; + } + } + + /** + * A builder for constructing an {@link RRCache} instance with customizable settings. + * + *

Allows configuring capacity, default TTL, random eviction behavior, eviction listener, + * and a pluggable eviction strategy. Call {@link #build()} to create the configured cache instance. + * + * @param the type of keys maintained by the cache + * @param the type of values stored in the cache + */ + public static class Builder { + private final int capacity; + private long defaultTTL = 0; + private Random random; + private BiConsumer evictionListener; + private EvictionStrategy evictionStrategy = new RRCache.PeriodicEvictionStrategy<>(100); + /** + * Creates a new {@code Builder} with the specified cache capacity. + * + * @param capacity the maximum number of entries the cache can hold; must be > 0 + * @throws IllegalArgumentException if {@code capacity} is less than or equal to 0 + */ + public Builder(int capacity) { + if (capacity <= 0) { + throw new IllegalArgumentException("Capacity must be > 0"); + } + this.capacity = capacity; + } + + /** + * Sets the default time-to-live (TTL) in milliseconds for cache entries. + * + * @param ttlMillis the TTL duration in milliseconds; must be >= 0 + * @return this builder instance for chaining + * @throws IllegalArgumentException if {@code ttlMillis} is negative + */ + public Builder defaultTTL(long ttlMillis) { + if (ttlMillis < 0) { + throw new IllegalArgumentException("Default TTL must be >= 0"); + } + this.defaultTTL = ttlMillis; + return this; + } + + /** + * Sets the {@link Random} instance to be used for random eviction selection. + * + * @param r a non-null {@code Random} instance + * @return this builder instance for chaining + * @throws IllegalArgumentException if {@code r} is {@code null} + */ + public Builder random(Random r) { + if (r == null) { + throw new IllegalArgumentException("Random must not be null"); + } + this.random = r; + return this; + } + + /** + * Sets an eviction listener to be notified when entries are evicted from the cache. + * + * @param listener a {@link BiConsumer} that accepts evicted keys and values; must not be {@code null} + * @return this builder instance for chaining + * @throws IllegalArgumentException if {@code listener} is {@code null} + */ + public Builder evictionListener(BiConsumer listener) { + if (listener == null) { + throw new IllegalArgumentException("Listener must not be null"); + } + this.evictionListener = listener; + return this; + } + + /** + * Builds and returns a new {@link RRCache} instance with the configured parameters. + * + * @return a fully configured {@code RRCache} instance + */ + public RRCache build() { + return new RRCache<>(this); + } + + /** + * Sets the eviction strategy used to determine when to clean up expired entries. + * + * @param strategy an {@link EvictionStrategy} implementation; must not be {@code null} + * @return this builder instance + * @throws IllegalArgumentException if {@code strategy} is {@code null} + */ + public Builder evictionStrategy(EvictionStrategy strategy) { + if (strategy == null) { + throw new IllegalArgumentException("Eviction strategy must not be null"); + } + this.evictionStrategy = strategy; + return this; + } + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/caches/RRCacheTest.java b/src/test/java/com/thealgorithms/datastructures/caches/RRCacheTest.java new file mode 100644 index 000000000000..100c73ea2a5b --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/caches/RRCacheTest.java @@ -0,0 +1,222 @@ +package com.thealgorithms.datastructures.caches; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; + +class RRCacheTest { + + private RRCache cache; + private Set evictedKeys; + private List evictedValues; + + @BeforeEach + void setUp() { + evictedKeys = new HashSet<>(); + evictedValues = new ArrayList<>(); + + cache = new RRCache.Builder(3) + .defaultTTL(1000) + .random(new Random(0)) + .evictionListener((k, v) -> { + evictedKeys.add(k); + evictedValues.add(v); + }) + .build(); + } + + @Test + void testPutAndGet() { + cache.put("a", "apple"); + Assertions.assertEquals("apple", cache.get("a")); + } + + @Test + void testOverwriteValue() { + cache.put("a", "apple"); + cache.put("a", "avocado"); + Assertions.assertEquals("avocado", cache.get("a")); + } + + @Test + void testExpiration() throws InterruptedException { + cache.put("temp", "value", 100); // short TTL + Thread.sleep(200); + Assertions.assertNull(cache.get("temp")); + Assertions.assertTrue(evictedKeys.contains("temp")); + } + + @Test + void testEvictionOnCapacity() { + cache.put("a", "alpha"); + cache.put("b", "bravo"); + cache.put("c", "charlie"); + cache.put("d", "delta"); // triggers eviction + + int size = cache.size(); + Assertions.assertEquals(3, size); + Assertions.assertEquals(1, evictedKeys.size()); + Assertions.assertEquals(1, evictedValues.size()); + } + + @Test + void testEvictionListener() { + cache.put("x", "one"); + cache.put("y", "two"); + cache.put("z", "three"); + cache.put("w", "four"); // one of x, y, z will be evicted + + Assertions.assertFalse(evictedKeys.isEmpty()); + Assertions.assertFalse(evictedValues.isEmpty()); + } + + @Test + void testHitsAndMisses() { + cache.put("a", "apple"); + Assertions.assertEquals("apple", cache.get("a")); + Assertions.assertNull(cache.get("b")); + Assertions.assertEquals(1, cache.getHits()); + Assertions.assertEquals(1, cache.getMisses()); + } + + @Test + void testSizeExcludesExpired() throws InterruptedException { + cache.put("a", "a", 100); + cache.put("b", "b", 100); + cache.put("c", "c", 100); + Thread.sleep(150); + Assertions.assertEquals(0, cache.size()); + } + + @Test + void testToStringDoesNotExposeExpired() throws InterruptedException { + cache.put("live", "alive"); + cache.put("dead", "gone", 100); + Thread.sleep(150); + String result = cache.toString(); + Assertions.assertTrue(result.contains("live")); + Assertions.assertFalse(result.contains("dead")); + } + + @Test + void testNullKeyGetThrows() { + Assertions.assertThrows(IllegalArgumentException.class, () -> cache.get(null)); + } + + @Test + void testPutNullKeyThrows() { + Assertions.assertThrows(IllegalArgumentException.class, () -> cache.put(null, "v")); + } + + @Test + void testPutNullValueThrows() { + Assertions.assertThrows(IllegalArgumentException.class, () -> cache.put("k", null)); + } + + @Test + void testPutNegativeTTLThrows() { + Assertions.assertThrows(IllegalArgumentException.class, () -> cache.put("k", "v", -1)); + } + + @Test + void testBuilderNegativeCapacityThrows() { + Assertions.assertThrows(IllegalArgumentException.class, () -> new RRCache.Builder<>(0)); + } + + @Test + void testBuilderNullRandomThrows() { + RRCache.Builder builder = new RRCache.Builder<>(1); + Assertions.assertThrows(IllegalArgumentException.class, () -> builder.random(null)); + } + + @Test + void testBuilderNullEvictionListenerThrows() { + RRCache.Builder builder = new RRCache.Builder<>(1); + Assertions.assertThrows(IllegalArgumentException.class, () -> builder.evictionListener(null)); + } + + @Test + void testEvictionListenerExceptionDoesNotCrash() { + RRCache listenerCache = new RRCache.Builder(1).evictionListener((k, v) -> { throw new RuntimeException("Exception"); }).build(); + + listenerCache.put("a", "a"); + listenerCache.put("b", "b"); // causes eviction but should not crash + Assertions.assertDoesNotThrow(() -> listenerCache.get("a")); + } + + @Test + void testTtlZeroThrowsIllegalArgumentException() { + Executable exec = () -> new RRCache.Builder(3).defaultTTL(-1).build(); + Assertions.assertThrows(IllegalArgumentException.class, exec); + } + + @Test + void testPeriodicEvictionStrategyEvictsAtInterval() throws InterruptedException { + RRCache periodicCache = new RRCache.Builder(10).defaultTTL(50).evictionStrategy(new RRCache.PeriodicEvictionStrategy<>(3)).build(); + + periodicCache.put("x", "1"); + Thread.sleep(100); + int ev1 = periodicCache.getEvictionStrategy().onAccess(periodicCache); + int ev2 = periodicCache.getEvictionStrategy().onAccess(periodicCache); + int ev3 = periodicCache.getEvictionStrategy().onAccess(periodicCache); + + Assertions.assertEquals(0, ev1); + Assertions.assertEquals(0, ev2); + Assertions.assertEquals(1, ev3, "Eviction should happen on the 3rd access"); + Assertions.assertEquals(0, periodicCache.size()); + } + + @Test + void testPeriodicEvictionStrategyThrowsExceptionIfIntervalLessThanOrEqual0() { + Executable executable = () -> new RRCache.Builder(10).defaultTTL(50).evictionStrategy(new RRCache.PeriodicEvictionStrategy<>(0)).build(); + + Assertions.assertThrows(IllegalArgumentException.class, executable); + } + + @Test + void testNoEvictionStrategyEvictsOnEachCall() throws InterruptedException { + RRCache noEvictionStrategyCache = new RRCache.Builder(10).defaultTTL(50).evictionStrategy(new RRCache.NoEvictionStrategy<>()).build(); + + noEvictionStrategyCache.put("x", "1"); + Thread.sleep(100); + int evicted = noEvictionStrategyCache.getEvictionStrategy().onAccess(noEvictionStrategyCache); + + Assertions.assertEquals(1, evicted); + } + + @Test + void testBuilderThrowsExceptionIfEvictionStrategyNull() { + Executable executable = () -> new RRCache.Builder(10).defaultTTL(50).evictionStrategy(null).build(); + + Assertions.assertThrows(IllegalArgumentException.class, executable); + } + + @Test + void testReturnsCorrectStrategyInstance() { + RRCache.EvictionStrategy strategy = new RRCache.NoEvictionStrategy<>(); + + RRCache newCache = new RRCache.Builder(10).defaultTTL(1000).evictionStrategy(strategy).build(); + + Assertions.assertSame(strategy, newCache.getEvictionStrategy(), "Returned strategy should be the same instance"); + } + + @Test + void testDefaultStrategyIsNoEviction() { + RRCache newCache = new RRCache.Builder(5).defaultTTL(1000).build(); + + Assertions.assertTrue(newCache.getEvictionStrategy() instanceof RRCache.PeriodicEvictionStrategy, "Default strategy should be NoEvictionStrategy"); + } + + @Test + void testGetEvictionStrategyIsNotNull() { + RRCache newCache = new RRCache.Builder(5).build(); + + Assertions.assertNotNull(newCache.getEvictionStrategy(), "Eviction strategy should never be null"); + } +} From 7da9c6dd63d77491c0c27742cf81fc0122846b5e Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Mon, 30 Jun 2025 20:58:21 +0200 Subject: [PATCH 114/146] Update DIRECTORY.md (#6329) --- DIRECTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 7a4c25afe9ca..6158a02f3cb5 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -131,6 +131,7 @@ - 📄 [LFUCache](src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java) - 📄 [LRUCache](src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java) - 📄 [MRUCache](src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java) + - 📄 [RRCache](src/main/java/com/thealgorithms/datastructures/caches/RRCache.java) - 📁 **crdt** - 📄 [GCounter](src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java) - 📄 [GSet](src/main/java/com/thealgorithms/datastructures/crdt/GSet.java) @@ -872,6 +873,7 @@ - 📄 [LFUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/LFUCacheTest.java) - 📄 [LRUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java) - 📄 [MRUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java) + - 📄 [RRCacheTest](src/test/java/com/thealgorithms/datastructures/caches/RRCacheTest.java) - 📁 **crdt** - 📄 [GCounterTest](src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java) - 📄 [GSetTest](src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java) From 55d08d657d13bd63408bea384ff5f6e15f1626e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 00:11:54 +0300 Subject: [PATCH 115/146] chore(deps): bump com.puppycrawl.tools:checkstyle from 10.26.0 to 10.26.1 (#6331) chore(deps): bump com.puppycrawl.tools:checkstyle Bumps [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) from 10.26.0 to 10.26.1. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.26.0...checkstyle-10.26.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-version: 10.26.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0b638c1fc709..d0cfbae9ca98 100644 --- a/pom.xml +++ b/pom.xml @@ -113,7 +113,7 @@ com.puppycrawl.tools checkstyle - 10.26.0 + 10.26.1 From ebf5c3d326502cbc6b22d84b489cea9996817bc7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 15:37:33 +0000 Subject: [PATCH 116/146] chore(deps): bump peter-evans/create-pull-request from 5 to 7 in /.github/workflows (#6330) chore(deps): bump peter-evans/create-pull-request in /.github/workflows Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 5 to 7. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/v5...v7) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/update-directorymd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-directorymd.yml b/.github/workflows/update-directorymd.yml index 6bc6485f61fb..53ad221e7742 100644 --- a/.github/workflows/update-directorymd.yml +++ b/.github/workflows/update-directorymd.yml @@ -31,7 +31,7 @@ jobs: git diff --cached --quiet || git commit -m "Update DIRECTORY.md" - name: Create Pull Request - uses: peter-evans/create-pull-request@v5 + uses: peter-evans/create-pull-request@v7 with: token: ${{ secrets.REPO_SCOPED_TOKEN }} branch: update-directory From 712ada5102be82b4807b0737ad70cfc0bca37935 Mon Sep 17 00:00:00 2001 From: codingmydna Date: Wed, 2 Jul 2025 21:51:56 +0900 Subject: [PATCH 117/146] Correct column pointer initialization in RowColumnWiseSorted2dArrayBinarySearch (#6333) --- ...owColumnWiseSorted2dArrayBinarySearch.java | 2 +- ...lumnWiseSorted2dArrayBinarySearchTest.java | 127 ++++++++++++++++++ 2 files changed, 128 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java b/src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java index 3b4b0b08377f..b40c7554d84b 100644 --- a/src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java +++ b/src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java @@ -29,7 +29,7 @@ public > int[] find(T[][] matrix, T key) { public static > int[] search(T[][] matrix, T target) { int rowPointer = 0; // The pointer at 0th row - int colPointer = matrix.length - 1; // The pointer at end column + int colPointer = matrix[0].length - 1; // The pointer at end column while (rowPointer < matrix.length && colPointer >= 0) { int comp = target.compareTo(matrix[rowPointer][colPointer]); diff --git a/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java b/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java index 39ac5bf037ea..8d1423cbeeb0 100644 --- a/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java +++ b/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java @@ -110,4 +110,131 @@ public void rowColumnSorted2dArrayBinarySearchTestNotFound() { assertEquals(expected[0], ans[0]); assertEquals(expected[1], ans[1]); } + + /** + * Tests for a WIDE rectangular matrix (3 rows, 4 columns) + */ + private static final Integer[][] WIDE_RECTANGULAR_MATRIX = { + {10, 20, 30, 40}, + {15, 25, 35, 45}, + {18, 28, 38, 48}, + }; + + @Test + public void rowColumnSorted2dArrayBinarySearchTestWideMatrixMiddle() { + Integer target = 25; // A value in the middle + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(WIDE_RECTANGULAR_MATRIX, target); + int[] expected = {1, 1}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestWideMatrixTopRightCorner() { + Integer target = 40; // The top-right corner element + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(WIDE_RECTANGULAR_MATRIX, target); + int[] expected = {0, 3}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestWideMatrixBottomLeftCorner() { + Integer target = 18; // The bottom-left corner element + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(WIDE_RECTANGULAR_MATRIX, target); + int[] expected = {2, 0}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestWideMatrixTopLeftCorner() { + Integer target = 10; // The top-left corner element + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(WIDE_RECTANGULAR_MATRIX, target); + int[] expected = {0, 0}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestWideMatrixBottomRightCorner() { + Integer target = 48; // The bottom-right corner element + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(WIDE_RECTANGULAR_MATRIX, target); + int[] expected = {2, 3}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestWideMatrixNotFound() { + Integer target = 99; // A value that does not exist + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(WIDE_RECTANGULAR_MATRIX, target); + int[] expected = {-1, -1}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + /** + * Tests for a TALL rectangular matrix (4 rows, 3 columns) + */ + private static final Integer[][] TALL_RECTANGULAR_MATRIX = { + {10, 20, 30}, + {15, 25, 35}, + {18, 28, 38}, + {21, 31, 41}, + }; + + @Test + public void rowColumnSorted2dArrayBinarySearchTestTallMatrixMiddle() { + Integer target = 28; // A value in the middle + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(TALL_RECTANGULAR_MATRIX, target); + int[] expected = {2, 1}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestTallMatrixTopRightCorner() { + Integer target = 30; // The top-right corner element + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(TALL_RECTANGULAR_MATRIX, target); + int[] expected = {0, 2}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestTallMatrixBottomLeftCorner() { + Integer target = 21; // The bottom-left corner element + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(TALL_RECTANGULAR_MATRIX, target); + int[] expected = {3, 0}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestTallMatrixTopLeftCorner() { + Integer target = 10; // The top-left corner element + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(TALL_RECTANGULAR_MATRIX, target); + int[] expected = {0, 0}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestTallMatrixBottomRightCorner() { + Integer target = 41; // The bottom-right corner element + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(TALL_RECTANGULAR_MATRIX, target); + int[] expected = {3, 2}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestTallMatrixNotFound() { + Integer target = 5; // A value that does not exist + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(TALL_RECTANGULAR_MATRIX, target); + int[] expected = {-1, -1}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } } From 58ac54cbdbc6d8f006e4fcb753f6ac416521702b Mon Sep 17 00:00:00 2001 From: Aditya Date: Fri, 4 Jul 2025 15:46:57 +0530 Subject: [PATCH 118/146] Add Freivalds' Algorithm for randomized matrix multiplication verification (#6340) --- ...mizedMatrixMultiplicationVerification.java | 64 +++++++++++++++++++ ...dMatrixMultiplicationVerificationTest.java | 41 ++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 src/main/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerification.java create mode 100644 src/test/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerificationTest.java diff --git a/src/main/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerification.java b/src/main/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerification.java new file mode 100644 index 000000000000..b5ac7076bfd6 --- /dev/null +++ b/src/main/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerification.java @@ -0,0 +1,64 @@ +package com.thealgorithms.randomized; + +import java.util.Random; + +public final class RandomizedMatrixMultiplicationVerification { + + private RandomizedMatrixMultiplicationVerification() { + // Prevent instantiation of utility class + } + + /** + * Verifies whether A × B == C using Freivalds' algorithm. + * @param A Left matrix + * @param B Right matrix + * @param C Product matrix to verify + * @param iterations Number of randomized checks + * @return true if likely A×B == C; false if definitely not + */ + public static boolean verify(int[][] a, int[][] b, int[][] c, int iterations) { + int n = a.length; + Random random = new Random(); + + for (int iter = 0; iter < iterations; iter++) { + // Step 1: Generate random 0/1 vector + int[] r = new int[n]; + for (int i = 0; i < n; i++) { + r[i] = random.nextInt(2); + } + + // Step 2: Compute br = b × r + int[] br = new int[n]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + br[i] += b[i][j] * r[j]; + } + } + + // Step 3: Compute a(br) + int[] abr = new int[n]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + abr[i] += a[i][j] * br[j]; + } + } + + // Step 4: Compute cr = c × r + int[] cr = new int[n]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + cr[i] += c[i][j] * r[j]; + } + } + + // Step 5: Compare abr and cr + for (int i = 0; i < n; i++) { + if (abr[i] != cr[i]) { + return false; + } + } + } + + return true; + } +} diff --git a/src/test/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerificationTest.java b/src/test/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerificationTest.java new file mode 100644 index 000000000000..330662ac2c52 --- /dev/null +++ b/src/test/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerificationTest.java @@ -0,0 +1,41 @@ +package com.thealgorithms.randomized; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class RandomizedMatrixMultiplicationVerificationTest { + + @Test + void testCorrectMultiplication() { + int[][] a = {{1, 2}, {3, 4}}; + int[][] b = {{5, 6}, {7, 8}}; + int[][] c = {{19, 22}, {43, 50}}; + assertTrue(RandomizedMatrixMultiplicationVerification.verify(a, b, c, 10)); + } + + @Test + void testIncorrectMultiplication() { + int[][] a = {{1, 2}, {3, 4}}; + int[][] b = {{5, 6}, {7, 8}}; + int[][] wrongC = {{20, 22}, {43, 51}}; + assertFalse(RandomizedMatrixMultiplicationVerification.verify(a, b, wrongC, 10)); + } + + @Test + void testLargeMatrix() { + int size = 100; + int[][] a = new int[size][size]; + int[][] b = new int[size][size]; + int[][] c = new int[size][size]; + + for (int i = 0; i < size; i++) { + a[i][i] = 1; + b[i][i] = 1; + c[i][i] = 1; + } + + assertTrue(RandomizedMatrixMultiplicationVerification.verify(a, b, c, 15)); + } +} From d709317b2e46fff578a8515f8fc89441cc4dd6c6 Mon Sep 17 00:00:00 2001 From: Aditya Date: Fri, 4 Jul 2025 15:53:49 +0530 Subject: [PATCH 119/146] Add RandomizedClosestPair Algorithm and Unit Tests (#6339) --- .../randomized/RandomizedClosestPair.java | 113 ++++++++++++++++++ .../randomized/RandomizedClosestPairTest.java | 30 +++++ 2 files changed, 143 insertions(+) create mode 100644 src/main/java/com/thealgorithms/randomized/RandomizedClosestPair.java create mode 100644 src/test/java/com/thealgorithms/randomized/RandomizedClosestPairTest.java diff --git a/src/main/java/com/thealgorithms/randomized/RandomizedClosestPair.java b/src/main/java/com/thealgorithms/randomized/RandomizedClosestPair.java new file mode 100644 index 000000000000..616f7fb7d7cf --- /dev/null +++ b/src/main/java/com/thealgorithms/randomized/RandomizedClosestPair.java @@ -0,0 +1,113 @@ +package com.thealgorithms.randomized; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Random; + +/** + * Randomized Closest Pair of Points Algorithm + * + * Use Case: + * - Efficiently finds the closest pair of points in a 2D plane. + * - Applicable in computational geometry, clustering, and graphics. + * + * Time Complexity: + * - Expected: O(n log n) using randomized divide and conquer + * + * @see Closest Pair of Points - Wikipedia + */ +public final class RandomizedClosestPair { + + // Prevent instantiation of utility class + private RandomizedClosestPair() { + throw new UnsupportedOperationException("Utility class"); + } + + public static class Point { + public final double x; + public final double y; + + public Point(double x, double y) { + this.x = x; + this.y = y; + } + } + + public static double findClosestPairDistance(Point[] points) { + List shuffled = new ArrayList<>(Arrays.asList(points)); + Collections.shuffle(shuffled, new Random()); + + Point[] px = shuffled.toArray(new Point[0]); + Arrays.sort(px, Comparator.comparingDouble(p -> p.x)); + + Point[] py = px.clone(); + Arrays.sort(py, Comparator.comparingDouble(p -> p.y)); + + return closestPair(px, py); + } + + private static double closestPair(Point[] px, Point[] py) { + int n = px.length; + if (n <= 3) { + return bruteForce(px); + } + + int mid = n / 2; + Point midPoint = px[mid]; + + Point[] qx = Arrays.copyOfRange(px, 0, mid); + Point[] rx = Arrays.copyOfRange(px, mid, n); + + List qy = new ArrayList<>(); + List ry = new ArrayList<>(); + for (Point p : py) { + if (p.x <= midPoint.x) { + qy.add(p); + } else { + ry.add(p); + } + } + + double d1 = closestPair(qx, qy.toArray(new Point[0])); + double d2 = closestPair(rx, ry.toArray(new Point[0])); + + double d = Math.min(d1, d2); + + List strip = new ArrayList<>(); + for (Point p : py) { + if (Math.abs(p.x - midPoint.x) < d) { + strip.add(p); + } + } + + return Math.min(d, stripClosest(strip, d)); + } + + private static double bruteForce(Point[] points) { + double min = Double.POSITIVE_INFINITY; + for (int i = 0; i < points.length; i++) { + for (int j = i + 1; j < points.length; j++) { + min = Math.min(min, distance(points[i], points[j])); + } + } + return min; + } + + private static double stripClosest(List strip, double d) { + double min = d; + int n = strip.size(); + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n && (strip.get(j).y - strip.get(i).y) < min; j++) { + min = Math.min(min, distance(strip.get(i), strip.get(j))); + } + } + return min; + } + + private static double distance(Point p1, Point p2) { + return Math.hypot(p1.x - p2.x, p1.y - p2.y); + } +} diff --git a/src/test/java/com/thealgorithms/randomized/RandomizedClosestPairTest.java b/src/test/java/com/thealgorithms/randomized/RandomizedClosestPairTest.java new file mode 100644 index 000000000000..fd739b743989 --- /dev/null +++ b/src/test/java/com/thealgorithms/randomized/RandomizedClosestPairTest.java @@ -0,0 +1,30 @@ +package com.thealgorithms.randomized; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.thealgorithms.randomized.RandomizedClosestPair.Point; +import org.junit.jupiter.api.Test; + +public class RandomizedClosestPairTest { + + @Test + public void testFindClosestPairDistance() { + Point[] points = {new Point(1, 1), new Point(2, 2), new Point(3, 3), new Point(8, 8), new Point(13, 13)}; + double result = RandomizedClosestPair.findClosestPairDistance(points); + assertEquals(Math.sqrt(2), result, 0.00001); + } + + @Test + public void testWithIdenticalPoints() { + Point[] points = {new Point(0, 0), new Point(0, 0), new Point(1, 1)}; + double result = RandomizedClosestPair.findClosestPairDistance(points); + assertEquals(0.0, result, 0.00001); + } + + @Test + public void testWithDistantPoints() { + Point[] points = {new Point(0, 0), new Point(5, 0), new Point(10, 0)}; + double result = RandomizedClosestPair.findClosestPairDistance(points); + assertEquals(5.0, result, 0.00001); + } +} From 841f9c3bbdbc443ad26e6bb2f1e2206bcc3fb55e Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Fri, 4 Jul 2025 12:40:46 +0200 Subject: [PATCH 120/146] Update DIRECTORY.md (#6341) Co-authored-by: siriak --- DIRECTORY.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 6158a02f3cb5..5a75847218b5 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -568,6 +568,8 @@ - 📁 **randomized** - 📄 [KargerMinCut](src/main/java/com/thealgorithms/randomized/KargerMinCut.java) - 📄 [MonteCarloIntegration](src/main/java/com/thealgorithms/randomized/MonteCarloIntegration.java) + - 📄 [RandomizedClosestPair](src/main/java/com/thealgorithms/randomized/RandomizedClosestPair.java) + - 📄 [RandomizedMatrixMultiplicationVerification](src/main/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerification.java) - 📄 [RandomizedQuickSort](src/main/java/com/thealgorithms/randomized/RandomizedQuickSort.java) - 📄 [ReservoirSampling](src/main/java/com/thealgorithms/randomized/ReservoirSampling.java) - 📁 **recursion** @@ -1233,6 +1235,8 @@ - 📁 **randomized** - 📄 [KargerMinCutTest](src/test/java/com/thealgorithms/randomized/KargerMinCutTest.java) - 📄 [MonteCarloIntegrationTest](src/test/java/com/thealgorithms/randomized/MonteCarloIntegrationTest.java) + - 📄 [RandomizedClosestPairTest](src/test/java/com/thealgorithms/randomized/RandomizedClosestPairTest.java) + - 📄 [RandomizedMatrixMultiplicationVerificationTest](src/test/java/com/thealgorithms/randomized/RandomizedMatrixMultiplicationVerificationTest.java) - 📄 [RandomizedQuickSortTest](src/test/java/com/thealgorithms/randomized/RandomizedQuickSortTest.java) - 📄 [ReservoirSamplingTest](src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java) - 📁 **recursion** From 4360807575d354c49bd046fcb30de8db81344bdd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Jul 2025 23:36:42 +0200 Subject: [PATCH 121/146] chore(deps): bump org.junit:junit-bom from 5.13.2 to 5.13.3 (#6343) Bumps [org.junit:junit-bom](https://github.com/junit-team/junit-framework) from 5.13.2 to 5.13.3. - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r5.13.2...r5.13.3) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-version: 5.13.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d0cfbae9ca98..ca2712d8c8ad 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ org.junit junit-bom - 5.13.2 + 5.13.3 pom import From c782f05ed439d7aa4a939eb65e69e1aac65cf9fe Mon Sep 17 00:00:00 2001 From: KevinMwita7 Date: Sat, 5 Jul 2025 16:29:46 +0300 Subject: [PATCH 122/146] Add cache with FIFO replacement policy (#6337) --- .../datastructures/caches/FIFOCache.java | 549 ++++++++++++++++++ .../datastructures/caches/FIFOCacheTest.java | 330 +++++++++++ 2 files changed, 879 insertions(+) create mode 100644 src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java create mode 100644 src/test/java/com/thealgorithms/datastructures/caches/FIFOCacheTest.java diff --git a/src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java b/src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java new file mode 100644 index 000000000000..fa048434a187 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java @@ -0,0 +1,549 @@ +package com.thealgorithms.datastructures.caches; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.BiConsumer; + +/** + * A thread-safe generic cache implementation using the First-In-First-Out eviction policy. + *

+ * The cache holds a fixed number of entries, defined by its capacity. When the cache is full and a + * new entry is added, the oldest entry in the cache is selected and evicted to make space. + *

+ * Optionally, entries can have a time-to-live (TTL) in milliseconds. If a TTL is set, entries will + * automatically expire and be removed upon access or insertion attempts. + *

+ * Features: + *

    + *
  • Removes oldest entry when capacity is exceeded
  • + *
  • Optional TTL (time-to-live in milliseconds) per entry or default TTL for all entries
  • + *
  • Thread-safe access using locking
  • + *
  • Hit and miss counters for cache statistics
  • + *
  • Eviction listener callback support
  • + *
+ * + * @param the type of keys maintained by this cache + * @param the type of mapped values + * See FIFO + * @author Kevin Babu (GitHub) + */ +public final class FIFOCache { + + private final int capacity; + private final long defaultTTL; + private final Map> cache; + private final Lock lock; + + private long hits = 0; + private long misses = 0; + private final BiConsumer evictionListener; + private final EvictionStrategy evictionStrategy; + + /** + * Internal structure to store value + expiry timestamp. + * + * @param the type of the value being cached + */ + private static class CacheEntry { + V value; + long expiryTime; + + /** + * Constructs a new {@code CacheEntry} with the specified value and time-to-live (TTL). + * If TTL is 0, the entry is kept indefinitely, that is, unless it is the first value, + * then it will be removed according to the FIFO principle + * + * @param value the value to cache + * @param ttlMillis the time-to-live in milliseconds + */ + CacheEntry(V value, long ttlMillis) { + this.value = value; + if (ttlMillis == 0) { + this.expiryTime = Long.MAX_VALUE; + } else { + this.expiryTime = System.currentTimeMillis() + ttlMillis; + } + } + + /** + * Checks if the cache entry has expired. + * + * @return {@code true} if the current time is past the expiration time; {@code false} otherwise + */ + boolean isExpired() { + return System.currentTimeMillis() > expiryTime; + } + } + + /** + * Constructs a new {@code FIFOCache} instance using the provided {@link Builder}. + * + *

This constructor initializes the cache with the specified capacity and default TTL, + * sets up internal data structures (a {@code LinkedHashMap} for cache entries and configures eviction. + * + * @param builder the {@code Builder} object containing configuration parameters + */ + private FIFOCache(Builder builder) { + this.capacity = builder.capacity; + this.defaultTTL = builder.defaultTTL; + this.cache = new LinkedHashMap<>(); + this.lock = new ReentrantLock(); + this.evictionListener = builder.evictionListener; + this.evictionStrategy = builder.evictionStrategy; + } + + /** + * Retrieves the value associated with the specified key from the cache. + * + *

If the key is not present or the corresponding entry has expired, this method + * returns {@code null}. If an expired entry is found, it will be removed and the + * eviction listener (if any) will be notified. Cache hit-and-miss statistics are + * also updated accordingly. + * + * @param key the key whose associated value is to be returned; must not be {@code null} + * @return the cached value associated with the key, or {@code null} if not present or expired + * @throws IllegalArgumentException if {@code key} is {@code null} + */ + public V get(K key) { + if (key == null) { + throw new IllegalArgumentException("Key must not be null"); + } + + lock.lock(); + try { + evictionStrategy.onAccess(this); + + CacheEntry entry = cache.get(key); + if (entry == null || entry.isExpired()) { + if (entry != null) { + cache.remove(key); + notifyEviction(key, entry.value); + } + misses++; + return null; + } + hits++; + return entry.value; + } finally { + lock.unlock(); + } + } + + /** + * Adds a key-value pair to the cache using the default time-to-live (TTL). + * + *

The key may overwrite an existing entry. The actual insertion is delegated + * to the overloaded {@link #put(K, V, long)} method. + * + * @param key the key to cache the value under + * @param value the value to be cached + */ + public void put(K key, V value) { + put(key, value, defaultTTL); + } + + /** + * Adds a key-value pair to the cache with a specified time-to-live (TTL). + * + *

If the key already exists, its value is removed, re-inserted at tail and its TTL is reset. + * If the key does not exist and the cache is full, the oldest entry is evicted to make space. + * Expired entries are also cleaned up prior to any eviction. The eviction listener + * is notified when an entry gets evicted. + * + * @param key the key to associate with the cached value; must not be {@code null} + * @param value the value to be cached; must not be {@code null} + * @param ttlMillis the time-to-live for this entry in milliseconds; must be >= 0 + * @throws IllegalArgumentException if {@code key} or {@code value} is {@code null}, or if {@code ttlMillis} is negative + */ + public void put(K key, V value, long ttlMillis) { + if (key == null || value == null) { + throw new IllegalArgumentException("Key and value must not be null"); + } + if (ttlMillis < 0) { + throw new IllegalArgumentException("TTL must be >= 0"); + } + + lock.lock(); + try { + // If key already exists, remove it + CacheEntry oldEntry = cache.remove(key); + if (oldEntry != null && !oldEntry.isExpired()) { + notifyEviction(key, oldEntry.value); + } + + // Evict expired entries to make space for new entry + evictExpired(); + + // If no expired entry was removed, remove the oldest + if (cache.size() >= capacity) { + Iterator>> it = cache.entrySet().iterator(); + if (it.hasNext()) { + Map.Entry> eldest = it.next(); + it.remove(); + notifyEviction(eldest.getKey(), eldest.getValue().value); + } + } + + // Insert new entry at tail + cache.put(key, new CacheEntry<>(value, ttlMillis)); + } finally { + lock.unlock(); + } + } + + /** + * Removes all expired entries from the cache. + * + *

This method iterates through the list of cached keys and checks each associated + * entry for expiration. Expired entries are removed the cache map. For each eviction, + * the eviction listener is notified. + */ + private int evictExpired() { + int count = 0; + Iterator>> it = cache.entrySet().iterator(); + + while (it.hasNext()) { + Map.Entry> entry = it.next(); + if (entry != null && entry.getValue().isExpired()) { + it.remove(); + notifyEviction(entry.getKey(), entry.getValue().value); + count++; + } + } + + return count; + } + + /** + * Removes the specified key and its associated entry from the cache. + * + * @param key the key to remove from the cache; + * @return the value associated with the key; or {@code null} if no such key exists + */ + public V removeKey(K key) { + if (key == null) { + throw new IllegalArgumentException("Key cannot be null"); + } + CacheEntry entry = cache.remove(key); + + // No such key in cache + if (entry == null) { + return null; + } + + notifyEviction(key, entry.value); + return entry.value; + } + + /** + * Notifies the eviction listener, if one is registered, that a key-value pair has been evicted. + * + *

If the {@code evictionListener} is not {@code null}, it is invoked with the provided key + * and value. Any exceptions thrown by the listener are caught and logged to standard error, + * preventing them from disrupting cache operations. + * + * @param key the key that was evicted + * @param value the value that was associated with the evicted key + */ + private void notifyEviction(K key, V value) { + if (evictionListener != null) { + try { + evictionListener.accept(key, value); + } catch (Exception e) { + System.err.println("Eviction listener failed: " + e.getMessage()); + } + } + } + + /** + * Returns the number of successful cache lookups (hits). + * + * @return the number of cache hits + */ + public long getHits() { + lock.lock(); + try { + return hits; + } finally { + lock.unlock(); + } + } + + /** + * Returns the number of failed cache lookups (misses), including expired entries. + * + * @return the number of cache misses + */ + public long getMisses() { + lock.lock(); + try { + return misses; + } finally { + lock.unlock(); + } + } + + /** + * Returns the current number of entries in the cache, excluding expired ones. + * + * @return the current cache size + */ + public int size() { + lock.lock(); + try { + evictionStrategy.onAccess(this); + + int count = 0; + for (CacheEntry entry : cache.values()) { + if (!entry.isExpired()) { + ++count; + } + } + return count; + } finally { + lock.unlock(); + } + } + + /** + * Removes all entries from the cache, regardless of their expiration status. + * + *

This method clears the internal cache map entirely, resets the hit-and-miss counters, + * and notifies the eviction listener (if any) for each removed entry. + * Note that expired entries are treated the same as active ones for the purpose of clearing. + * + *

This operation acquires the internal lock to ensure thread safety. + */ + public void clear() { + lock.lock(); + try { + for (Map.Entry> entry : cache.entrySet()) { + notifyEviction(entry.getKey(), entry.getValue().value); + } + cache.clear(); + hits = 0; + misses = 0; + } finally { + lock.unlock(); + } + } + + /** + * Returns a set of all keys currently stored in the cache that have not expired. + * + *

This method iterates through the cache and collects the keys of all non-expired entries. + * Expired entries are ignored but not removed. If you want to ensure expired entries are cleaned up, + * consider invoking {@link EvictionStrategy#onAccess(FIFOCache)} or calling {@link #evictExpired()} manually. + * + *

This operation acquires the internal lock to ensure thread safety. + * + * @return a set containing all non-expired keys currently in the cache + */ + public Set getAllKeys() { + lock.lock(); + try { + Set keys = new LinkedHashSet<>(); + + for (Map.Entry> entry : cache.entrySet()) { + if (!entry.getValue().isExpired()) { + keys.add(entry.getKey()); + } + } + + return keys; + } finally { + lock.unlock(); + } + } + + /** + * Returns the current {@link EvictionStrategy} used by this cache instance. + + * @return the eviction strategy currently assigned to this cache + */ + public EvictionStrategy getEvictionStrategy() { + return evictionStrategy; + } + + /** + * Returns a string representation of the cache, including metadata and current non-expired entries. + * + *

The returned string includes the cache's capacity, current size (excluding expired entries), + * hit-and-miss counts, and a map of all non-expired key-value pairs. This method acquires a lock + * to ensure thread-safe access. + * + * @return a string summarizing the state of the cache + */ + @Override + public String toString() { + lock.lock(); + try { + Map visible = new LinkedHashMap<>(); + for (Map.Entry> entry : cache.entrySet()) { + if (!entry.getValue().isExpired()) { + visible.put(entry.getKey(), entry.getValue().value); + } + } + return String.format("Cache(capacity=%d, size=%d, hits=%d, misses=%d, entries=%s)", capacity, visible.size(), hits, misses, visible); + } finally { + lock.unlock(); + } + } + + /** + * A strategy interface for controlling when expired entries are evicted from the cache. + * + *

Implementations decide whether and when to trigger {@link FIFOCache#evictExpired()} based + * on cache usage patterns. This allows for flexible eviction behaviour such as periodic cleanup, + * or no automatic cleanup. + * + * @param the type of keys maintained by the cache + * @param the type of cached values + */ + public interface EvictionStrategy { + /** + * Called on each cache access (e.g., {@link FIFOCache#get(Object)}) to optionally trigger eviction. + * + * @param cache the cache instance on which this strategy is applied + * @return the number of expired entries evicted during this access + */ + int onAccess(FIFOCache cache); + } + + /** + * An eviction strategy that performs eviction of expired entries on each call. + * + * @param the type of keys + * @param the type of values + */ + public static class ImmediateEvictionStrategy implements EvictionStrategy { + @Override + public int onAccess(FIFOCache cache) { + return cache.evictExpired(); + } + } + + /** + * An eviction strategy that triggers eviction on every fixed number of accesses. + * + *

This deterministic strategy ensures cleanup occurs at predictable intervals, + * ideal for moderately active caches where memory usage is a concern. + * + * @param the type of keys + * @param the type of values + */ + public static class PeriodicEvictionStrategy implements EvictionStrategy { + private final int interval; + private final AtomicInteger counter = new AtomicInteger(); + + /** + * Constructs a periodic eviction strategy. + * + * @param interval the number of accesses between evictions; must be > 0 + * @throws IllegalArgumentException if {@code interval} is less than or equal to 0 + */ + public PeriodicEvictionStrategy(int interval) { + if (interval <= 0) { + throw new IllegalArgumentException("Interval must be > 0"); + } + this.interval = interval; + } + + @Override + public int onAccess(FIFOCache cache) { + if (counter.incrementAndGet() % interval == 0) { + return cache.evictExpired(); + } + + return 0; + } + } + + /** + * A builder for constructing a {@link FIFOCache} instance with customizable settings. + * + *

Allows configuring capacity, default TTL, eviction listener, and a pluggable eviction + * strategy. Call {@link #build()} to create the configured cache instance. + * + * @param the type of keys maintained by the cache + * @param the type of values stored in the cache + */ + public static class Builder { + private final int capacity; + private long defaultTTL = 0; + private BiConsumer evictionListener; + private EvictionStrategy evictionStrategy = new FIFOCache.ImmediateEvictionStrategy<>(); + /** + * Creates a new {@code Builder} with the specified cache capacity. + * + * @param capacity the maximum number of entries the cache can hold; must be > 0 + * @throws IllegalArgumentException if {@code capacity} is less than or equal to 0 + */ + public Builder(int capacity) { + if (capacity <= 0) { + throw new IllegalArgumentException("Capacity must be > 0"); + } + this.capacity = capacity; + } + + /** + * Sets the default time-to-live (TTL) in milliseconds for cache entries. + * + * @param ttlMillis the TTL duration in milliseconds; must be >= 0 + * @return this builder instance for chaining + * @throws IllegalArgumentException if {@code ttlMillis} is negative + */ + public Builder defaultTTL(long ttlMillis) { + if (ttlMillis < 0) { + throw new IllegalArgumentException("Default TTL must be >= 0"); + } + this.defaultTTL = ttlMillis; + return this; + } + + /** + * Sets an eviction listener to be notified when entries are evicted from the cache. + * + * @param listener a {@link BiConsumer} that accepts evicted keys and values; must not be {@code null} + * @return this builder instance for chaining + * @throws IllegalArgumentException if {@code listener} is {@code null} + */ + public Builder evictionListener(BiConsumer listener) { + if (listener == null) { + throw new IllegalArgumentException("Listener must not be null"); + } + this.evictionListener = listener; + return this; + } + + /** + * Builds and returns a new {@link FIFOCache} instance with the configured parameters. + * + * @return a fully configured {@code FIFOCache} instance + */ + public FIFOCache build() { + return new FIFOCache<>(this); + } + + /** + * Sets the eviction strategy used to determine when to clean up expired entries. + * + * @param strategy an {@link EvictionStrategy} implementation; must not be {@code null} + * @return this builder instance + * @throws IllegalArgumentException if {@code strategy} is {@code null} + */ + public Builder evictionStrategy(EvictionStrategy strategy) { + if (strategy == null) { + throw new IllegalArgumentException("Eviction strategy must not be null"); + } + this.evictionStrategy = strategy; + return this; + } + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/caches/FIFOCacheTest.java b/src/test/java/com/thealgorithms/datastructures/caches/FIFOCacheTest.java new file mode 100644 index 000000000000..5f250e6ca3fd --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/caches/FIFOCacheTest.java @@ -0,0 +1,330 @@ +package com.thealgorithms.datastructures.caches; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; + +class FIFOCacheTest { + private FIFOCache cache; + private Set evictedKeys; + private List evictedValues; + + @BeforeEach + void setUp() { + evictedKeys = new HashSet<>(); + evictedValues = new ArrayList<>(); + + cache = new FIFOCache.Builder(3) + .defaultTTL(1000) + .evictionListener((k, v) -> { + evictedKeys.add(k); + evictedValues.add(v); + }) + .build(); + } + + @Test + void testPutAndGet() { + cache.put("a", "apple"); + Assertions.assertEquals("apple", cache.get("a")); + } + + @Test + void testOverwriteValue() { + cache.put("a", "apple"); + cache.put("a", "avocado"); + Assertions.assertEquals("avocado", cache.get("a")); + } + + @Test + void testExpiration() throws InterruptedException { + cache.put("temp", "value", 100); + Thread.sleep(200); + Assertions.assertNull(cache.get("temp")); + Assertions.assertTrue(evictedKeys.contains("temp")); + } + + @Test + void testEvictionOnCapacity() { + cache.put("a", "alpha"); + cache.put("b", "bravo"); + cache.put("c", "charlie"); + cache.put("d", "delta"); + + int size = cache.size(); + Assertions.assertEquals(3, size); + Assertions.assertEquals(1, evictedKeys.size()); + Assertions.assertEquals(1, evictedValues.size()); + } + + @Test + void testEvictionListener() { + cache.put("x", "one"); + cache.put("y", "two"); + cache.put("z", "three"); + cache.put("w", "four"); + + Assertions.assertFalse(evictedKeys.isEmpty()); + Assertions.assertFalse(evictedValues.isEmpty()); + } + + @Test + void testHitsAndMisses() { + cache.put("a", "apple"); + Assertions.assertEquals("apple", cache.get("a")); + Assertions.assertNull(cache.get("b")); + Assertions.assertEquals(1, cache.getHits()); + Assertions.assertEquals(1, cache.getMisses()); + } + + @Test + void testSizeExcludesExpired() throws InterruptedException { + cache.put("a", "a", 100); + cache.put("b", "b", 100); + cache.put("c", "c", 100); + Thread.sleep(150); + Assertions.assertEquals(0, cache.size()); + } + + @Test + void testSizeIncludesFresh() { + cache.put("a", "a", 1000); + cache.put("b", "b", 1000); + cache.put("c", "c", 1000); + Assertions.assertEquals(3, cache.size()); + } + + @Test + void testToStringDoesNotExposeExpired() throws InterruptedException { + cache.put("live", "alive"); + cache.put("dead", "gone", 100); + Thread.sleep(150); + String result = cache.toString(); + Assertions.assertTrue(result.contains("live")); + Assertions.assertFalse(result.contains("dead")); + } + + @Test + void testNullKeyGetThrows() { + Assertions.assertThrows(IllegalArgumentException.class, () -> cache.get(null)); + } + + @Test + void testPutNullKeyThrows() { + Assertions.assertThrows(IllegalArgumentException.class, () -> cache.put(null, "v")); + } + + @Test + void testPutNullValueThrows() { + Assertions.assertThrows(IllegalArgumentException.class, () -> cache.put("k", null)); + } + + @Test + void testPutNegativeTTLThrows() { + Assertions.assertThrows(IllegalArgumentException.class, () -> cache.put("k", "v", -1)); + } + + @Test + void testBuilderNegativeCapacityThrows() { + Assertions.assertThrows(IllegalArgumentException.class, () -> new FIFOCache.Builder<>(0)); + } + + @Test + void testBuilderNullEvictionListenerThrows() { + FIFOCache.Builder builder = new FIFOCache.Builder<>(1); + Assertions.assertThrows(IllegalArgumentException.class, () -> builder.evictionListener(null)); + } + + @Test + void testEvictionListenerExceptionDoesNotCrash() { + FIFOCache listenerCache = new FIFOCache.Builder(1).evictionListener((k, v) -> { throw new RuntimeException("Exception"); }).build(); + + listenerCache.put("a", "a"); + listenerCache.put("b", "b"); + Assertions.assertDoesNotThrow(() -> listenerCache.get("a")); + } + + @Test + void testTtlZeroThrowsIllegalArgumentException() { + Executable exec = () -> new FIFOCache.Builder(3).defaultTTL(-1).build(); + Assertions.assertThrows(IllegalArgumentException.class, exec); + } + + @Test + void testPeriodicEvictionStrategyEvictsAtInterval() throws InterruptedException { + FIFOCache periodicCache = new FIFOCache.Builder(10).defaultTTL(50).evictionStrategy(new FIFOCache.PeriodicEvictionStrategy<>(3)).build(); + + periodicCache.put("x", "1"); + Thread.sleep(100); + int ev1 = periodicCache.getEvictionStrategy().onAccess(periodicCache); + int ev2 = periodicCache.getEvictionStrategy().onAccess(periodicCache); + int ev3 = periodicCache.getEvictionStrategy().onAccess(periodicCache); + + Assertions.assertEquals(0, ev1); + Assertions.assertEquals(0, ev2); + Assertions.assertEquals(1, ev3, "Eviction should happen on the 3rd access"); + Assertions.assertEquals(0, periodicCache.size()); + } + + @Test + void testPeriodicEvictionStrategyThrowsExceptionIfIntervalLessThanOrEqual0() { + Executable executable = () -> new FIFOCache.Builder(10).defaultTTL(50).evictionStrategy(new FIFOCache.PeriodicEvictionStrategy<>(0)).build(); + + Assertions.assertThrows(IllegalArgumentException.class, executable); + } + + @Test + void testImmediateEvictionStrategyStrategyEvictsOnEachCall() throws InterruptedException { + FIFOCache immediateEvictionStrategy = new FIFOCache.Builder(10).defaultTTL(50).evictionStrategy(new FIFOCache.ImmediateEvictionStrategy<>()).build(); + + immediateEvictionStrategy.put("x", "1"); + Thread.sleep(100); + int evicted = immediateEvictionStrategy.getEvictionStrategy().onAccess(immediateEvictionStrategy); + + Assertions.assertEquals(1, evicted); + } + + @Test + void testBuilderThrowsExceptionIfEvictionStrategyNull() { + Executable executable = () -> new FIFOCache.Builder(10).defaultTTL(50).evictionStrategy(null).build(); + + Assertions.assertThrows(IllegalArgumentException.class, executable); + } + + @Test + void testReturnsCorrectStrategyInstance() { + FIFOCache.EvictionStrategy strategy = new FIFOCache.ImmediateEvictionStrategy<>(); + + FIFOCache newCache = new FIFOCache.Builder(10).defaultTTL(1000).evictionStrategy(strategy).build(); + + Assertions.assertSame(strategy, newCache.getEvictionStrategy(), "Returned strategy should be the same instance"); + } + + @Test + void testDefaultStrategyIsImmediateEvictionStrategy() { + FIFOCache newCache = new FIFOCache.Builder(5).defaultTTL(1000).build(); + + Assertions.assertTrue(newCache.getEvictionStrategy() instanceof FIFOCache.ImmediateEvictionStrategy, "Default strategy should be ImmediateEvictionStrategyStrategy"); + } + + @Test + void testGetEvictionStrategyIsNotNull() { + FIFOCache newCache = new FIFOCache.Builder(5).build(); + + Assertions.assertNotNull(newCache.getEvictionStrategy(), "Eviction strategy should never be null"); + } + + @Test + void testRemoveKeyRemovesExistingKey() { + cache.put("A", "Alpha"); + cache.put("B", "Beta"); + + Assertions.assertEquals("Alpha", cache.get("A")); + Assertions.assertEquals("Beta", cache.get("B")); + + String removed = cache.removeKey("A"); + Assertions.assertEquals("Alpha", removed); + + Assertions.assertNull(cache.get("A")); + Assertions.assertEquals(1, cache.size()); + } + + @Test + void testRemoveKeyReturnsNullIfKeyNotPresent() { + cache.put("X", "X-ray"); + + Assertions.assertNull(cache.removeKey("NonExistent")); + Assertions.assertEquals(1, cache.size()); + } + + @Test + void testRemoveKeyHandlesExpiredEntry() throws InterruptedException { + FIFOCache expiringCache = new FIFOCache.Builder(2).defaultTTL(100).evictionStrategy(new FIFOCache.ImmediateEvictionStrategy<>()).build(); + + expiringCache.put("T", "Temporary"); + + Thread.sleep(200); + + String removed = expiringCache.removeKey("T"); + Assertions.assertEquals("Temporary", removed); + Assertions.assertNull(expiringCache.get("T")); + } + + @Test + void testRemoveKeyThrowsIfKeyIsNull() { + Assertions.assertThrows(IllegalArgumentException.class, () -> cache.removeKey(null)); + } + + @Test + void testRemoveKeyTriggersEvictionListener() { + AtomicInteger evictedCount = new AtomicInteger(); + + FIFOCache localCache = new FIFOCache.Builder(2).evictionListener((key, value) -> evictedCount.incrementAndGet()).build(); + + localCache.put("A", "Apple"); + localCache.put("B", "Banana"); + + localCache.removeKey("A"); + + Assertions.assertEquals(1, evictedCount.get(), "Eviction listener should have been called once"); + } + + @Test + void testRemoveKeyDoestNotAffectOtherKeys() { + cache.put("A", "Alpha"); + cache.put("B", "Beta"); + cache.put("C", "Gamma"); + + cache.removeKey("B"); + + Assertions.assertEquals("Alpha", cache.get("A")); + Assertions.assertNull(cache.get("B")); + Assertions.assertEquals("Gamma", cache.get("C")); + } + + @Test + void testEvictionListenerExceptionDoesNotPropagate() { + FIFOCache localCache = new FIFOCache.Builder(1).evictionListener((key, value) -> { throw new RuntimeException(); }).build(); + + localCache.put("A", "Apple"); + + Assertions.assertDoesNotThrow(() -> localCache.put("B", "Beta")); + } + + @Test + void testGetKeysReturnsAllFreshKeys() { + cache.put("A", "Alpha"); + cache.put("B", "Beta"); + cache.put("G", "Gamma"); + + Set expectedKeys = Set.of("A", "B", "G"); + Assertions.assertEquals(expectedKeys, cache.getAllKeys()); + } + + @Test + void testGetKeysIgnoresExpiredKeys() throws InterruptedException { + cache.put("A", "Alpha"); + cache.put("B", "Beta"); + cache.put("G", "Gamma", 100); + + Set expectedKeys = Set.of("A", "B"); + Thread.sleep(200); + Assertions.assertEquals(expectedKeys, cache.getAllKeys()); + } + + @Test + void testClearRemovesAllEntries() { + cache.put("A", "Alpha"); + cache.put("B", "Beta"); + cache.put("G", "Gamma"); + + cache.clear(); + Assertions.assertEquals(0, cache.size()); + } +} From 9b4dec0b06470bff898c108fe2ed19927c93e08c Mon Sep 17 00:00:00 2001 From: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> Date: Sat, 5 Jul 2025 17:07:10 +0200 Subject: [PATCH 123/146] Update DIRECTORY.md (#6344) Co-authored-by: siriak --- DIRECTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 5a75847218b5..9697dbc09869 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -128,6 +128,7 @@ - 📁 **buffers** - 📄 [CircularBuffer](src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java) - 📁 **caches** + - 📄 [FIFOCache](src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java) - 📄 [LFUCache](src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java) - 📄 [LRUCache](src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java) - 📄 [MRUCache](src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java) @@ -872,6 +873,7 @@ - 📁 **buffers** - 📄 [CircularBufferTest](src/test/java/com/thealgorithms/datastructures/buffers/CircularBufferTest.java) - 📁 **caches** + - 📄 [FIFOCacheTest](src/test/java/com/thealgorithms/datastructures/caches/FIFOCacheTest.java) - 📄 [LFUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/LFUCacheTest.java) - 📄 [LRUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java) - 📄 [MRUCacheTest](src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java) From 350f1496573c218f1d3796ed80811d4f46060125 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Sun, 6 Jul 2025 19:03:02 +0200 Subject: [PATCH 124/146] Add parameterized tests for BitSwap (#6347) --- .../bitmanipulation/BitSwap.java | 19 +++++- .../bitmanipulation/BitSwapTest.java | 63 ++++++++++++++++--- 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java b/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java index 40b3097b1276..d8c207567ba6 100644 --- a/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java +++ b/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java @@ -1,12 +1,27 @@ package com.thealgorithms.bitmanipulation; +/** + * Utility class for performing bit-swapping operations on integers. + * This class cannot be instantiated. + */ public final class BitSwap { private BitSwap() { } - /* - * @brief Swaps the bits at the position posA and posB from data + + /** + * Swaps two bits at specified positions in an integer. + * + * @param data The input integer whose bits need to be swapped + * @param posA The position of the first bit (0-based, from least significant) + * @param posB The position of the second bit (0-based, from least significant) + * @return The modified value with swapped bits + * @throws IllegalArgumentException if either position is negative or ≥ 32 */ public static int bitSwap(int data, final int posA, final int posB) { + if (posA < 0 || posA >= Integer.SIZE || posB < 0 || posB >= Integer.SIZE) { + throw new IllegalArgumentException("Bit positions must be between 0 and 31"); + } + if (SingleBitOperations.getBit(data, posA) != SingleBitOperations.getBit(data, posB)) { data ^= (1 << posA) ^ (1 << posB); } diff --git a/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java b/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java index 40de770e0c66..9d888d056453 100644 --- a/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java +++ b/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java @@ -1,13 +1,62 @@ package com.thealgorithms.bitmanipulation; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Test; -public class BitSwapTest { - @Test - void testHighestSetBit() { - assertEquals(3, BitSwap.bitSwap(3, 0, 1)); - assertEquals(5, BitSwap.bitSwap(6, 0, 1)); - assertEquals(7, BitSwap.bitSwap(7, 1, 1)); +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class BitSwapTest { + + @ParameterizedTest(name = "Additional cases: data={0}, posA={1}, posB={2} -> expected={3}") + @MethodSource("provideAdditionalCases") + void testAdditionalCases(int data, int posA, int posB, int expected) { + assertEquals(expected, BitSwap.bitSwap(data, posA, posB)); + } + + @ParameterizedTest(name = "Swap different bits: data={0}, posA={1}, posB={2} -> expected={3}") + @MethodSource("provideDifferentBitsCases") + void swapDifferentBits(int data, int posA, int posB, int expected) { + assertEquals(expected, BitSwap.bitSwap(data, posA, posB)); + } + + @ParameterizedTest(name = "Swap same bits: data={0}, posA={1}, posB={2} should not change") + @MethodSource("provideSameBitsCases") + void swapSameBits(int data, int posA, int posB) { + assertEquals(data, BitSwap.bitSwap(data, posA, posB)); + } + + @ParameterizedTest(name = "Edge cases: data={0}, posA={1}, posB={2} -> expected={3}") + @MethodSource("provideEdgeCases") + void testEdgeCases(int data, int posA, int posB, int expected) { + assertEquals(expected, BitSwap.bitSwap(data, posA, posB)); + } + + @ParameterizedTest(name = "Invalid positions: data={0}, posA={1}, posB={2} should throw") + @MethodSource("provideInvalidPositions") + void invalidPositionThrowsException(int data, int posA, int posB) { + assertThrows(IllegalArgumentException.class, () -> BitSwap.bitSwap(data, posA, posB)); + } + + static Stream provideAdditionalCases() { + return Stream.of(Arguments.of(3, 0, 1, 3), Arguments.of(6, 0, 1, 5), Arguments.of(7, 1, 1, 7)); + } + + static Stream provideDifferentBitsCases() { + return Stream.of(Arguments.of(0b01, 0, 1, 0b10)); + } + + static Stream provideSameBitsCases() { + return Stream.of(Arguments.of(0b111, 0, 2), Arguments.of(0b0, 1, 3), Arguments.of(0b1010, 1, 3), Arguments.of(-1, 5, 5)); + } + + static Stream provideEdgeCases() { + return Stream.of(Arguments.of(Integer.MIN_VALUE, 31, 0, 1), Arguments.of(0, 0, 31, 0)); + } + + static Stream provideInvalidPositions() { + return Stream.of(Arguments.of(0, -1, 0), Arguments.of(0, 0, 32), Arguments.of(0, -5, 33), Arguments.of(0, Integer.MIN_VALUE, Integer.MAX_VALUE)); } } From 4b6006c87656d718e5f928865758a6e4908657e1 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Sun, 6 Jul 2025 23:19:50 +0200 Subject: [PATCH 125/146] refactor: improve code and test coverage for `MapReduce` example (#6348) refactor: improve code and test coverage for MapReduce example --- .../com/thealgorithms/misc/MapReduce.java | 47 +++++++++---------- .../com/thealgorithms/misc/MapReduceTest.java | 22 +++------ 2 files changed, 30 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/thealgorithms/misc/MapReduce.java b/src/main/java/com/thealgorithms/misc/MapReduce.java index c076957344f9..d98b2ee2dd03 100644 --- a/src/main/java/com/thealgorithms/misc/MapReduce.java +++ b/src/main/java/com/thealgorithms/misc/MapReduce.java @@ -7,35 +7,34 @@ import java.util.function.Function; import java.util.stream.Collectors; -/* -* MapReduce is a programming model for processing and generating large data sets with a parallel, -distributed algorithm on a cluster. -* It has two main steps: the Map step, where the data is divided into smaller chunks and processed in parallel, -and the Reduce step, where the results from the Map step are combined to produce the final output. -* Wikipedia link : https://en.wikipedia.org/wiki/MapReduce -*/ - +/** + * MapReduce is a programming model for processing and generating large data sets + * using a parallel, distributed algorithm on a cluster. + * It consists of two main phases: + * - Map: the input data is split into smaller chunks and processed in parallel. + * - Reduce: the results from the Map phase are aggregated to produce the final output. + * + * See also: https://en.wikipedia.org/wiki/MapReduce + */ public final class MapReduce { + private MapReduce() { } - /* - *Counting all the words frequency within a sentence. - */ - public static String mapreduce(String sentence) { - List wordList = Arrays.stream(sentence.split(" ")).toList(); - // Map step - Map wordCounts = wordList.stream().collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting())); - - // Reduce step - StringBuilder result = new StringBuilder(); - wordCounts.forEach((word, count) -> result.append(word).append(": ").append(count).append(",")); + /** + * Counts the frequency of each word in a given sentence using a simple MapReduce-style approach. + * + * @param sentence the input sentence + * @return a string representing word frequencies in the format "word: count,word: count,..." + */ + public static String countWordFrequencies(String sentence) { + // Map phase: split the sentence into words + List words = Arrays.asList(sentence.trim().split("\\s+")); - // Removing the last ',' if it exists - if (!result.isEmpty()) { - result.setLength(result.length() - 1); - } + // Group and count occurrences of each word, maintain insertion order + Map wordCounts = words.stream().collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting())); - return result.toString(); + // Reduce phase: format the result + return wordCounts.entrySet().stream().map(entry -> entry.getKey() + ": " + entry.getValue()).collect(Collectors.joining(",")); } } diff --git a/src/test/java/com/thealgorithms/misc/MapReduceTest.java b/src/test/java/com/thealgorithms/misc/MapReduceTest.java index c79c40701cc1..748dd0a563cf 100644 --- a/src/test/java/com/thealgorithms/misc/MapReduceTest.java +++ b/src/test/java/com/thealgorithms/misc/MapReduceTest.java @@ -2,22 +2,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; public class MapReduceTest { - @Test - public void testMapReduceWithSingleWordSentence() { - String oneWordSentence = "Hactober"; - String result = MapReduce.mapreduce(oneWordSentence); - - assertEquals("Hactober: 1", result); - } - - @Test - public void testMapReduceWithMultipleWordSentence() { - String multipleWordSentence = "I Love Love HactoberFest"; - String result = MapReduce.mapreduce(multipleWordSentence); - - assertEquals("I: 1,Love: 2,HactoberFest: 1", result); + @ParameterizedTest + @CsvSource({"'hello world', 'hello: 1,world: 1'", "'one one two', 'one: 2,two: 1'", "'a a a a', 'a: 4'", "' spaced out ', 'spaced: 1,out: 1'"}) + void testCountWordFrequencies(String input, String expected) { + String result = MapReduce.countWordFrequencies(input); + assertEquals(expected, result); } } From 8512f127ce2c1a32a7909dcca1f475ccaf73e49e Mon Sep 17 00:00:00 2001 From: pushkar0406 <136320165+pushkar0406@users.noreply.github.com> Date: Mon, 7 Jul 2025 16:52:40 +0530 Subject: [PATCH 126/146] Fix the formatting issue with clang-format (#6346) --- .../sorts/AdaptiveMergeSortTest.java | 89 ++++++++++++++++++ .../com/thealgorithms/sorts/BogoSortTest.java | 84 +++++++++++++++++ .../thealgorithms/sorts/BubbleSortTest.java | 84 +++++++++++++++++ .../thealgorithms/sorts/GnomeSortTest.java | 90 +++++++++++++++++++ .../sorts/InsertionSortTest.java | 84 +++++++++++++++++ .../com/thealgorithms/sorts/SlowSortTest.java | 84 +++++++++++++++++ 6 files changed, 515 insertions(+) diff --git a/src/test/java/com/thealgorithms/sorts/AdaptiveMergeSortTest.java b/src/test/java/com/thealgorithms/sorts/AdaptiveMergeSortTest.java index 9d94b165d81b..8cb401802c4b 100644 --- a/src/test/java/com/thealgorithms/sorts/AdaptiveMergeSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/AdaptiveMergeSortTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import java.util.Objects; import org.junit.jupiter.api.Test; public class AdaptiveMergeSortTest { @@ -50,4 +51,92 @@ public void testSortSingleElement() { Integer[] result = adaptiveMergeSort.sort(input); assertArrayEquals(expected, result); } + + @Test + public void testSortAlreadySortedArray() { + AdaptiveMergeSort adaptiveMergeSort = new AdaptiveMergeSort(); + Integer[] inputArray = {-12, -6, -3, 0, 2, 2, 13, 46}; + Integer[] outputArray = adaptiveMergeSort.sort(inputArray); + Integer[] expectedOutput = {-12, -6, -3, 0, 2, 2, 13, 46}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void testSortReversedSortedArray() { + AdaptiveMergeSort adaptiveMergeSort = new AdaptiveMergeSort(); + Integer[] inputArray = {46, 13, 2, 2, 0, -3, -6, -12}; + Integer[] outputArray = adaptiveMergeSort.sort(inputArray); + Integer[] expectedOutput = {-12, -6, -3, 0, 2, 2, 13, 46}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void testSortAllEqualArray() { + AdaptiveMergeSort adaptiveMergeSort = new AdaptiveMergeSort(); + Integer[] inputArray = {2, 2, 2, 2, 2}; + Integer[] outputArray = adaptiveMergeSort.sort(inputArray); + Integer[] expectedOutput = {2, 2, 2, 2, 2}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void testSortMixedCaseStrings() { + AdaptiveMergeSort adaptiveMergeSort = new AdaptiveMergeSort(); + String[] inputArray = {"banana", "Apple", "apple", "Banana"}; + String[] expectedOutput = {"Apple", "Banana", "apple", "banana"}; + String[] outputArray = adaptiveMergeSort.sort(inputArray); + assertArrayEquals(expectedOutput, outputArray); + } + + /** + * Custom Comparable class for testing. + **/ + static class Person implements Comparable { + String name; + int age; + + Person(String name, int age) { + this.name = name; + this.age = age; + } + + @Override + public int compareTo(Person o) { + return Integer.compare(this.age, o.age); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Person person = (Person) o; + return age == person.age && Objects.equals(name, person.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + } + + @Test + public void testSortCustomObjects() { + AdaptiveMergeSort adaptiveMergeSort = new AdaptiveMergeSort(); + Person[] inputArray = { + new Person("Alice", 32), + new Person("Bob", 25), + new Person("Charlie", 28), + }; + Person[] expectedOutput = { + new Person("Bob", 25), + new Person("Charlie", 28), + new Person("Alice", 32), + }; + Person[] outputArray = adaptiveMergeSort.sort(inputArray); + assertArrayEquals(expectedOutput, outputArray); + } } diff --git a/src/test/java/com/thealgorithms/sorts/BogoSortTest.java b/src/test/java/com/thealgorithms/sorts/BogoSortTest.java index 3ebfb7a305b0..dc4f9e1c25bb 100644 --- a/src/test/java/com/thealgorithms/sorts/BogoSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/BogoSortTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import java.util.Objects; import org.junit.jupiter.api.Test; public class BogoSortTest { @@ -63,4 +64,87 @@ public void bogoSortDuplicateStringArray() { String[] expectedOutput = {"a", "b", "b", "c", "d", "d", "h", "s"}; assertArrayEquals(outputArray, expectedOutput); } + + @Test + public void bogoSortAlreadySortedArray() { + Integer[] inputArray = {-12, -6, -3, 0, 2, 2, 13, 46}; + Integer[] outputArray = bogoSort.sort(inputArray); + Integer[] expectedOutput = {-12, -6, -3, 0, 2, 2, 13, 46}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bogoSortReversedSortedArray() { + Integer[] inputArray = {46, 13, 2, 2, 0, -3, -6, -12}; + Integer[] outputArray = bogoSort.sort(inputArray); + Integer[] expectedOutput = {-12, -6, -3, 0, 2, 2, 13, 46}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bogoSortAllEqualArray() { + Integer[] inputArray = {2, 2, 2, 2, 2}; + Integer[] outputArray = bogoSort.sort(inputArray); + Integer[] expectedOutput = {2, 2, 2, 2, 2}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bogoSortMixedCaseStrings() { + String[] inputArray = {"banana", "Apple", "apple", "Banana"}; + String[] expectedOutput = {"Apple", "Banana", "apple", "banana"}; + String[] outputArray = bogoSort.sort(inputArray); + assertArrayEquals(expectedOutput, outputArray); + } + + /** + * Custom Comparable class for testing. + **/ + static class Person implements Comparable { + String name; + int age; + + Person(String name, int age) { + this.name = name; + this.age = age; + } + + @Override + public int compareTo(Person o) { + return Integer.compare(this.age, o.age); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Person person = (Person) o; + return age == person.age && Objects.equals(name, person.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + } + + @Test + public void bogoSortCustomObjects() { + Person[] inputArray = { + new Person("Alice", 32), + new Person("Bob", 25), + new Person("Charlie", 28), + }; + Person[] expectedOutput = { + new Person("Bob", 25), + new Person("Charlie", 28), + new Person("Alice", 32), + }; + Person[] outputArray = bogoSort.sort(inputArray); + assertArrayEquals(expectedOutput, outputArray); + } } diff --git a/src/test/java/com/thealgorithms/sorts/BubbleSortTest.java b/src/test/java/com/thealgorithms/sorts/BubbleSortTest.java index 8690a3f5435c..3b99dca13b06 100644 --- a/src/test/java/com/thealgorithms/sorts/BubbleSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/BubbleSortTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import java.util.Objects; import org.junit.jupiter.api.Test; /** @@ -91,4 +92,87 @@ public void bubbleSortStringArray() { }; assertArrayEquals(outputArray, expectedOutput); } + + @Test + public void bubbleSortAlreadySortedArray() { + Integer[] inputArray = {-12, -6, -3, 0, 2, 2, 13, 46}; + Integer[] outputArray = bubbleSort.sort(inputArray); + Integer[] expectedOutput = {-12, -6, -3, 0, 2, 2, 13, 46}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bubbleSortReversedSortedArray() { + Integer[] inputArray = {46, 13, 2, 2, 0, -3, -6, -12}; + Integer[] outputArray = bubbleSort.sort(inputArray); + Integer[] expectedOutput = {-12, -6, -3, 0, 2, 2, 13, 46}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bubbleSortAllEqualArray() { + Integer[] inputArray = {2, 2, 2, 2, 2}; + Integer[] outputArray = bubbleSort.sort(inputArray); + Integer[] expectedOutput = {2, 2, 2, 2, 2}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bubbleSortMixedCaseStrings() { + String[] inputArray = {"banana", "Apple", "apple", "Banana"}; + String[] expectedOutput = {"Apple", "Banana", "apple", "banana"}; + String[] outputArray = bubbleSort.sort(inputArray); + assertArrayEquals(expectedOutput, outputArray); + } + + /** + * Custom Comparable class for testing. + **/ + static class Person implements Comparable { + String name; + int age; + + Person(String name, int age) { + this.name = name; + this.age = age; + } + + @Override + public int compareTo(Person o) { + return Integer.compare(this.age, o.age); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Person person = (Person) o; + return age == person.age && Objects.equals(name, person.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + } + + @Test + public void bubbleSortCustomObjects() { + Person[] inputArray = { + new Person("Alice", 32), + new Person("Bob", 25), + new Person("Charlie", 28), + }; + Person[] expectedOutput = { + new Person("Bob", 25), + new Person("Charlie", 28), + new Person("Alice", 32), + }; + Person[] outputArray = bubbleSort.sort(inputArray); + assertArrayEquals(expectedOutput, outputArray); + } } diff --git a/src/test/java/com/thealgorithms/sorts/GnomeSortTest.java b/src/test/java/com/thealgorithms/sorts/GnomeSortTest.java index d86546472580..1d875d1fad0d 100644 --- a/src/test/java/com/thealgorithms/sorts/GnomeSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/GnomeSortTest.java @@ -1,7 +1,9 @@ package com.thealgorithms.sorts; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import java.util.Objects; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -79,4 +81,92 @@ public void gnomeSortDuplicateStringArray() { gnomeSort.sort(inputArray); assertThat(inputArray).isEqualTo(expectedOutput); } + + @Test + @DisplayName("GnomeSort for sorted Array") + public void testSortAlreadySortedArray() { + Integer[] inputArray = {-12, -6, -3, 0, 2, 2, 13, 46}; + Integer[] outputArray = gnomeSort.sort(inputArray); + Integer[] expectedOutput = {-12, -6, -3, 0, 2, 2, 13, 46}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + @DisplayName("GnomeSort for reversed sorted Array") + public void testSortReversedSortedArray() { + Integer[] inputArray = {46, 13, 2, 2, 0, -3, -6, -12}; + Integer[] outputArray = gnomeSort.sort(inputArray); + Integer[] expectedOutput = {-12, -6, -3, 0, 2, 2, 13, 46}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + @DisplayName("GnomeSort for All equal Array") + public void testSortAllEqualArray() { + Integer[] inputArray = {2, 2, 2, 2, 2}; + Integer[] outputArray = gnomeSort.sort(inputArray); + Integer[] expectedOutput = {2, 2, 2, 2, 2}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + @DisplayName("GnomeSort String Array with mixed cases") + public void testSortMixedCaseStrings() { + String[] inputArray = {"banana", "Apple", "apple", "Banana"}; + String[] expectedOutput = {"Apple", "Banana", "apple", "banana"}; + String[] outputArray = gnomeSort.sort(inputArray); + assertArrayEquals(expectedOutput, outputArray); + } + + /** + * Custom Comparable class for testing. + **/ + static class Person implements Comparable { + String name; + int age; + + Person(String name, int age) { + this.name = name; + this.age = age; + } + + @Override + public int compareTo(Person o) { + return Integer.compare(this.age, o.age); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Person person = (Person) o; + return age == person.age && Objects.equals(name, person.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + } + + @Test + @DisplayName("GnomeSort Custom Object Array") + public void testSortCustomObjects() { + Person[] inputArray = { + new Person("Alice", 32), + new Person("Bob", 25), + new Person("Charlie", 28), + }; + Person[] expectedOutput = { + new Person("Bob", 25), + new Person("Charlie", 28), + new Person("Alice", 32), + }; + Person[] outputArray = gnomeSort.sort(inputArray); + assertArrayEquals(expectedOutput, outputArray); + } } diff --git a/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java b/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java index 78744973355d..32a2a807295b 100644 --- a/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.Objects; import java.util.function.Function; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -111,4 +112,87 @@ private void testWithRandomArray(Function sortAlgorithm) { Double[] sorted = sortAlgorithm.apply(array); assertTrue(SortUtils.isSorted(sorted)); } + + @Test + public void testSortAlreadySortedArray() { + Integer[] inputArray = {-12, -6, -3, 0, 2, 2, 13, 46}; + Integer[] outputArray = insertionSort.sort(inputArray); + Integer[] expectedOutput = {-12, -6, -3, 0, 2, 2, 13, 46}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void testSortReversedSortedArray() { + Integer[] inputArray = {46, 13, 2, 2, 0, -3, -6, -12}; + Integer[] outputArray = insertionSort.sort(inputArray); + Integer[] expectedOutput = {-12, -6, -3, 0, 2, 2, 13, 46}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void testSortAllEqualArray() { + Integer[] inputArray = {2, 2, 2, 2, 2}; + Integer[] outputArray = insertionSort.sort(inputArray); + Integer[] expectedOutput = {2, 2, 2, 2, 2}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void testSortMixedCaseStrings() { + String[] inputArray = {"banana", "Apple", "apple", "Banana"}; + String[] expectedOutput = {"Apple", "Banana", "apple", "banana"}; + String[] outputArray = insertionSort.sort(inputArray); + assertArrayEquals(expectedOutput, outputArray); + } + + /** + * Custom Comparable class for testing. + **/ + static class Person implements Comparable { + String name; + int age; + + Person(String name, int age) { + this.name = name; + this.age = age; + } + + @Override + public int compareTo(Person o) { + return Integer.compare(this.age, o.age); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Person person = (Person) o; + return age == person.age && Objects.equals(name, person.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + } + + @Test + public void testSortCustomObjects() { + Person[] inputArray = { + new Person("Alice", 32), + new Person("Bob", 25), + new Person("Charlie", 28), + }; + Person[] expectedOutput = { + new Person("Bob", 25), + new Person("Charlie", 28), + new Person("Alice", 32), + }; + Person[] outputArray = insertionSort.sort(inputArray); + assertArrayEquals(expectedOutput, outputArray); + } } diff --git a/src/test/java/com/thealgorithms/sorts/SlowSortTest.java b/src/test/java/com/thealgorithms/sorts/SlowSortTest.java index d4d9eaa1c275..5fbdf8477092 100644 --- a/src/test/java/com/thealgorithms/sorts/SlowSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/SlowSortTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import java.util.Objects; import org.junit.jupiter.api.Test; /** @@ -76,4 +77,87 @@ public void slowSortStringSymbolArray() { String[] expectedOutput = {"(a", "(b", ")", "a", "au", "auk", "auk", "bhy", "cba", "cba", "cbf", "á", "ó"}; assertArrayEquals(outputArray, expectedOutput); } + + @Test + public void testSortAlreadySortedArray() { + Integer[] inputArray = {-12, -6, -3, 0, 2, 2, 13, 46}; + Integer[] outputArray = slowSort.sort(inputArray); + Integer[] expectedOutput = {-12, -6, -3, 0, 2, 2, 13, 46}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void testSortReversedSortedArray() { + Integer[] inputArray = {46, 13, 2, 2, 0, -3, -6, -12}; + Integer[] outputArray = slowSort.sort(inputArray); + Integer[] expectedOutput = {-12, -6, -3, 0, 2, 2, 13, 46}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void testSortAllEqualArray() { + Integer[] inputArray = {2, 2, 2, 2, 2}; + Integer[] outputArray = slowSort.sort(inputArray); + Integer[] expectedOutput = {2, 2, 2, 2, 2}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void testSortMixedCaseStrings() { + String[] inputArray = {"banana", "Apple", "apple", "Banana"}; + String[] expectedOutput = {"Apple", "Banana", "apple", "banana"}; + String[] outputArray = slowSort.sort(inputArray); + assertArrayEquals(expectedOutput, outputArray); + } + + /** + * Custom Comparable class for testing. + **/ + static class Person implements Comparable { + String name; + int age; + + Person(String name, int age) { + this.name = name; + this.age = age; + } + + @Override + public int compareTo(Person o) { + return Integer.compare(this.age, o.age); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Person person = (Person) o; + return age == person.age && Objects.equals(name, person.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, age); + } + } + + @Test + public void testSortCustomObjects() { + Person[] inputArray = { + new Person("Alice", 32), + new Person("Bob", 25), + new Person("Charlie", 28), + }; + Person[] expectedOutput = { + new Person("Bob", 25), + new Person("Charlie", 28), + new Person("Alice", 32), + }; + Person[] outputArray = slowSort.sort(inputArray); + assertArrayEquals(expectedOutput, outputArray); + } } From 2f5bc8c24281d69872fd645e5cb908144f1f21a1 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Mon, 7 Jul 2025 13:29:10 +0200 Subject: [PATCH 127/146] refactor: improve median calculator class design and readability (#6349) --- .../misc/MedianOfRunningArray.java | 82 ++++++++++++------- .../misc/MedianOfRunningArrayTest.java | 80 +++++++++--------- 2 files changed, 93 insertions(+), 69 deletions(-) diff --git a/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java b/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java index 62013ee31183..95f86f63f720 100644 --- a/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java +++ b/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java @@ -4,50 +4,74 @@ import java.util.PriorityQueue; /** - * @author shrutisheoran + * A generic abstract class to compute the median of a dynamically growing stream of numbers. + * + * @param the number type, must extend Number and be Comparable + * + * Usage: + * Extend this class and implement {@code calculateAverage(T a, T b)} to define how averaging is done. */ public abstract class MedianOfRunningArray> { - private PriorityQueue maxHeap; - private PriorityQueue minHeap; + private final PriorityQueue maxHeap; // Lower half (max-heap) + private final PriorityQueue minHeap; // Upper half (min-heap) - // Constructor public MedianOfRunningArray() { - this.maxHeap = new PriorityQueue<>(Collections.reverseOrder()); // Max Heap - this.minHeap = new PriorityQueue<>(); // Min Heap + this.maxHeap = new PriorityQueue<>(Collections.reverseOrder()); + this.minHeap = new PriorityQueue<>(); } - /* - Inserting lower half of array to max Heap - and upper half to min heap + /** + * Inserts a new number into the data structure. + * + * @param element the number to insert */ - public void insert(final T e) { - if (!minHeap.isEmpty() && e.compareTo(minHeap.peek()) < 0) { - maxHeap.offer(e); - if (maxHeap.size() > minHeap.size() + 1) { - minHeap.offer(maxHeap.poll()); - } + public final void insert(final T element) { + if (!minHeap.isEmpty() && element.compareTo(minHeap.peek()) < 0) { + maxHeap.offer(element); + balanceHeapsIfNeeded(); } else { - minHeap.offer(e); - if (minHeap.size() > maxHeap.size() + 1) { - maxHeap.offer(minHeap.poll()); - } + minHeap.offer(element); + balanceHeapsIfNeeded(); } } - /* - Returns median at any given point + /** + * Returns the median of the current elements. + * + * @return the median value + * @throws IllegalArgumentException if no elements have been inserted */ - public T median() { + public final T getMedian() { if (maxHeap.isEmpty() && minHeap.isEmpty()) { - throw new IllegalArgumentException("Enter at least 1 element, Median of empty list is not defined!"); - } else if (maxHeap.size() == minHeap.size()) { - T maxHeapTop = maxHeap.peek(); - T minHeapTop = minHeap.peek(); - return calculateAverage(maxHeapTop, minHeapTop); + throw new IllegalArgumentException("Median is undefined for an empty data set."); } - return maxHeap.size() > minHeap.size() ? maxHeap.peek() : minHeap.peek(); + + if (maxHeap.size() == minHeap.size()) { + return calculateAverage(maxHeap.peek(), minHeap.peek()); + } + + return (maxHeap.size() > minHeap.size()) ? maxHeap.peek() : minHeap.peek(); } - public abstract T calculateAverage(T a, T b); + /** + * Calculates the average between two values. + * Concrete subclasses must define how averaging works (e.g., for Integer, Double, etc.). + * + * @param a first number + * @param b second number + * @return the average of a and b + */ + protected abstract T calculateAverage(T a, T b); + + /** + * Balances the two heaps so that their sizes differ by at most 1. + */ + private void balanceHeapsIfNeeded() { + if (maxHeap.size() > minHeap.size() + 1) { + minHeap.offer(maxHeap.poll()); + } else if (minHeap.size() > maxHeap.size() + 1) { + maxHeap.offer(minHeap.poll()); + } + } } diff --git a/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java b/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java index e64ae1b741b6..f41953035846 100644 --- a/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java +++ b/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java @@ -11,12 +11,12 @@ */ public class MedianOfRunningArrayTest { - private static final String EXCEPTION_MESSAGE = "Enter at least 1 element, Median of empty list is not defined!"; + private static final String EXCEPTION_MESSAGE = "Median is undefined for an empty data set."; @Test public void testWhenInvalidInoutProvidedShouldThrowException() { var stream = new MedianOfRunningArrayInteger(); - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> stream.median()); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, stream::getMedian); assertEquals(exception.getMessage(), EXCEPTION_MESSAGE); } @@ -24,68 +24,68 @@ public void testWhenInvalidInoutProvidedShouldThrowException() { public void testWithNegativeValues() { var stream = new MedianOfRunningArrayInteger(); stream.insert(-1); - assertEquals(-1, stream.median()); + assertEquals(-1, stream.getMedian()); stream.insert(-2); - assertEquals(-1, stream.median()); + assertEquals(-1, stream.getMedian()); stream.insert(-3); - assertEquals(-2, stream.median()); + assertEquals(-2, stream.getMedian()); } @Test public void testWithSingleValues() { var stream = new MedianOfRunningArrayInteger(); stream.insert(-1); - assertEquals(-1, stream.median()); + assertEquals(-1, stream.getMedian()); } @Test public void testWithRandomValues() { var stream = new MedianOfRunningArrayInteger(); stream.insert(10); - assertEquals(10, stream.median()); + assertEquals(10, stream.getMedian()); stream.insert(5); - assertEquals(7, stream.median()); + assertEquals(7, stream.getMedian()); stream.insert(20); - assertEquals(10, stream.median()); + assertEquals(10, stream.getMedian()); stream.insert(15); - assertEquals(12, stream.median()); + assertEquals(12, stream.getMedian()); stream.insert(25); - assertEquals(15, stream.median()); + assertEquals(15, stream.getMedian()); stream.insert(30); - assertEquals(17, stream.median()); + assertEquals(17, stream.getMedian()); stream.insert(35); - assertEquals(20, stream.median()); + assertEquals(20, stream.getMedian()); stream.insert(1); - assertEquals(17, stream.median()); + assertEquals(17, stream.getMedian()); } @Test public void testWithNegativeAndPositiveValues() { var stream = new MedianOfRunningArrayInteger(); stream.insert(-1); - assertEquals(-1, stream.median()); + assertEquals(-1, stream.getMedian()); stream.insert(2); - assertEquals(0, stream.median()); + assertEquals(0, stream.getMedian()); stream.insert(-3); - assertEquals(-1, stream.median()); + assertEquals(-1, stream.getMedian()); } @Test public void testWithDuplicateValues() { var stream = new MedianOfRunningArrayInteger(); stream.insert(-1); - assertEquals(-1, stream.median()); + assertEquals(-1, stream.getMedian()); stream.insert(-1); - assertEquals(-1, stream.median()); + assertEquals(-1, stream.getMedian()); stream.insert(-1); - assertEquals(-1, stream.median()); + assertEquals(-1, stream.getMedian()); } @Test @@ -98,20 +98,20 @@ public void testWithDuplicateValuesB() { stream.insert(20); stream.insert(0); stream.insert(50); - assertEquals(10, stream.median()); + assertEquals(10, stream.getMedian()); } @Test public void testWithLargeValues() { var stream = new MedianOfRunningArrayInteger(); stream.insert(1000000); - assertEquals(1000000, stream.median()); + assertEquals(1000000, stream.getMedian()); stream.insert(12000); - assertEquals(506000, stream.median()); + assertEquals(506000, stream.getMedian()); stream.insert(15000000); - assertEquals(1000000, stream.median()); + assertEquals(1000000, stream.getMedian()); stream.insert(2300000); - assertEquals(1650000, stream.median()); + assertEquals(1650000, stream.getMedian()); } @Test @@ -120,7 +120,7 @@ public void testWithLargeCountOfValues() { for (int i = 1; i <= 1000; i++) { stream.insert(i); } - assertEquals(500, stream.median()); + assertEquals(500, stream.getMedian()); } @Test @@ -129,7 +129,7 @@ public void testWithThreeValuesInDescendingOrder() { stream.insert(30); stream.insert(20); stream.insert(10); - assertEquals(20, stream.median()); + assertEquals(20, stream.getMedian()); } @Test @@ -138,7 +138,7 @@ public void testWithThreeValuesInOrder() { stream.insert(10); stream.insert(20); stream.insert(30); - assertEquals(20, stream.median()); + assertEquals(20, stream.getMedian()); } @Test @@ -147,7 +147,7 @@ public void testWithThreeValuesNotInOrderA() { stream.insert(30); stream.insert(10); stream.insert(20); - assertEquals(20, stream.median()); + assertEquals(20, stream.getMedian()); } @Test @@ -156,46 +156,46 @@ public void testWithThreeValuesNotInOrderB() { stream.insert(20); stream.insert(10); stream.insert(30); - assertEquals(20, stream.median()); + assertEquals(20, stream.getMedian()); } @Test public void testWithFloatValues() { var stream = new MedianOfRunningArrayFloat(); stream.insert(20.0f); - assertEquals(20.0f, stream.median()); + assertEquals(20.0f, stream.getMedian()); stream.insert(10.5f); - assertEquals(15.25f, stream.median()); + assertEquals(15.25f, stream.getMedian()); stream.insert(30.0f); - assertEquals(20.0f, stream.median()); + assertEquals(20.0f, stream.getMedian()); } @Test public void testWithByteValues() { var stream = new MedianOfRunningArrayByte(); stream.insert((byte) 120); - assertEquals((byte) 120, stream.median()); + assertEquals((byte) 120, stream.getMedian()); stream.insert((byte) -120); - assertEquals((byte) 0, stream.median()); + assertEquals((byte) 0, stream.getMedian()); stream.insert((byte) 127); - assertEquals((byte) 120, stream.median()); + assertEquals((byte) 120, stream.getMedian()); } @Test public void testWithLongValues() { var stream = new MedianOfRunningArrayLong(); stream.insert(120000000L); - assertEquals(120000000L, stream.median()); + assertEquals(120000000L, stream.getMedian()); stream.insert(92233720368547757L); - assertEquals(46116860244273878L, stream.median()); + assertEquals(46116860244273878L, stream.getMedian()); } @Test public void testWithDoubleValues() { var stream = new MedianOfRunningArrayDouble(); stream.insert(12345.67891); - assertEquals(12345.67891, stream.median()); + assertEquals(12345.67891, stream.getMedian()); stream.insert(23456789.98); - assertEquals(11734567.83, stream.median(), .01); + assertEquals(11734567.83, stream.getMedian(), .01); } } From fa2ca9db390e9549be6501bc22c2e4453185b16e Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Mon, 7 Jul 2025 23:29:52 +0200 Subject: [PATCH 128/146] refactor: improve PythagoreanTriple logic and add parameterized tests (#6350) --- .../maths/PythagoreanTriple.java | 45 +++++++++++-------- .../maths/PythagoreanTripleTest.java | 24 +++++----- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java b/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java index f535e9e6929b..2780b113d904 100644 --- a/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java +++ b/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java @@ -1,36 +1,43 @@ package com.thealgorithms.maths; /** - * https://en.wikipedia.org/wiki/Pythagorean_triple + * Utility class to check if three integers form a Pythagorean triple. + * A Pythagorean triple consists of three positive integers a, b, and c, + * such that a² + b² = c². + * + * Common examples: + * - (3, 4, 5) + * - (5, 12, 13) + * + * Reference: https://en.wikipedia.org/wiki/Pythagorean_triple */ public final class PythagoreanTriple { - private PythagoreanTriple() { - } - public static void main(String[] args) { - assert isPythagTriple(3, 4, 5); - assert isPythagTriple(5, 12, 13); - assert isPythagTriple(6, 8, 10); - assert !isPythagTriple(10, 20, 30); - assert !isPythagTriple(6, 8, 100); - assert !isPythagTriple(-1, -1, 1); + private PythagoreanTriple() { } /** - * Check if a,b,c are a Pythagorean Triple + * Checks whether three integers form a Pythagorean triple. + * The order of parameters does not matter. * - * @param a x/y component length of a right triangle - * @param b y/x component length of a right triangle - * @param c hypotenuse length of a right triangle - * @return boolean true if a, b, c satisfy the Pythagorean theorem, - * otherwise - * false + * @param a one side length + * @param b another side length + * @param c another side length + * @return {@code true} if (a, b, c) can form a Pythagorean triple, otherwise {@code false} */ public static boolean isPythagTriple(int a, int b, int c) { if (a <= 0 || b <= 0 || c <= 0) { return false; - } else { - return (a * a) + (b * b) == (c * c); } + + // Sort the sides so the largest is treated as hypotenuse + int[] sides = {a, b, c}; + java.util.Arrays.sort(sides); + + int x = sides[0]; + int y = sides[1]; + int hypotenuse = sides[2]; + + return x * x + y * y == hypotenuse * hypotenuse; } } diff --git a/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java b/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java index 13ea58155dec..75219dc47b47 100644 --- a/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java +++ b/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java @@ -1,22 +1,24 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; public class PythagoreanTripleTest { + @ParameterizedTest + @CsvSource({"3, 4, 5, true", "6, 8, 10, true", "9, 12, 15, true", "12, 16, 20, true", "15, 20, 25, true", "18, 24, 30, true", "5, 20, 30, false", "6, 8, 100, false", "-2, -2, 2, false", "0, 0, 0, false", "5, 5, 5, false"}) + void testIsPythagoreanTriple(int a, int b, int c, boolean expected) { + assertEquals(expected, PythagoreanTriple.isPythagTriple(a, b, c)); + } + @Test - public void testPythagoreanTriple() { - assertTrue(PythagoreanTriple.isPythagTriple(3, 4, 5)); - assertTrue(PythagoreanTriple.isPythagTriple(6, 8, 10)); - assertTrue(PythagoreanTriple.isPythagTriple(9, 12, 15)); - assertTrue(PythagoreanTriple.isPythagTriple(12, 16, 20)); - assertTrue(PythagoreanTriple.isPythagTriple(15, 20, 25)); - assertTrue(PythagoreanTriple.isPythagTriple(18, 24, 30)); - assertFalse(PythagoreanTriple.isPythagTriple(5, 20, 30)); - assertFalse(PythagoreanTriple.isPythagTriple(6, 8, 100)); - assertFalse(PythagoreanTriple.isPythagTriple(-2, -2, 2)); + void testUnorderedInputStillValid() { + // Should still detect Pythagorean triples regardless of argument order + assertTrue(PythagoreanTriple.isPythagTriple(5, 3, 4)); + assertTrue(PythagoreanTriple.isPythagTriple(13, 12, 5)); } } From 6c3049530f54b451e708ec78dafd31403447d840 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Tue, 8 Jul 2025 09:50:06 +0200 Subject: [PATCH 129/146] refactor: optimize ValidParentheses methods and add parameterized tests (#6352) --- .../strings/ValidParentheses.java | 84 +++++++++---------- .../strings/ValidParenthesesTest.java | 26 ++---- 2 files changed, 46 insertions(+), 64 deletions(-) diff --git a/src/main/java/com/thealgorithms/strings/ValidParentheses.java b/src/main/java/com/thealgorithms/strings/ValidParentheses.java index 629fee495d84..25a72f379dec 100644 --- a/src/main/java/com/thealgorithms/strings/ValidParentheses.java +++ b/src/main/java/com/thealgorithms/strings/ValidParentheses.java @@ -1,59 +1,53 @@ package com.thealgorithms.strings; -// Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine -// if the input string is valid. An input string is valid if: Open brackets must be closed by -// the same type of brackets. Open brackets must be closed in the correct order. Every close -// bracket has a corresponding open bracket of the same type. +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Map; + +/** + * Validates if a given string has valid matching parentheses. + *

+ * A string is considered valid if: + *

    + *
  • Open brackets are closed by the same type of brackets.
  • + *
  • Brackets are closed in the correct order.
  • + *
  • Every closing bracket has a corresponding open bracket of the same type.
  • + *
+ * + * Allowed characters: '(', ')', '{', '}', '[', ']' + */ public final class ValidParentheses { private ValidParentheses() { } + + private static final Map BRACKET_PAIRS = Map.of(')', '(', '}', '{', ']', '['); + + /** + * Checks if the input string has valid parentheses. + * + * @param s the string containing only bracket characters + * @return true if valid, false otherwise + * @throws IllegalArgumentException if the string contains invalid characters or is null + */ public static boolean isValid(String s) { - char[] stack = new char[s.length()]; - int head = 0; + if (s == null) { + throw new IllegalArgumentException("Input string cannot be null"); + } + + Deque stack = new ArrayDeque<>(); + for (char c : s.toCharArray()) { - switch (c) { - case '{': - case '[': - case '(': - stack[head++] = c; - break; - case '}': - if (head == 0 || stack[--head] != '{') { - return false; - } - break; - case ')': - if (head == 0 || stack[--head] != '(') { - return false; - } - break; - case ']': - if (head == 0 || stack[--head] != '[') { + if (BRACKET_PAIRS.containsValue(c)) { + stack.push(c); // opening bracket + } else if (BRACKET_PAIRS.containsKey(c)) { + if (stack.isEmpty() || stack.pop() != BRACKET_PAIRS.get(c)) { return false; } - break; - default: - throw new IllegalArgumentException("Unexpected character: " + c); - } - } - return head == 0; - } - public static boolean isValidParentheses(String s) { - int i = -1; - char[] stack = new char[s.length()]; - String openBrackets = "({["; - String closeBrackets = ")}]"; - for (char ch : s.toCharArray()) { - if (openBrackets.indexOf(ch) != -1) { - stack[++i] = ch; } else { - if (i >= 0 && openBrackets.indexOf(stack[i]) == closeBrackets.indexOf(ch)) { - i--; - } else { - return false; - } + throw new IllegalArgumentException("Unexpected character: " + c); } } - return i == -1; + + return stack.isEmpty(); } } diff --git a/src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java b/src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java index 2b6884c91c8f..23d41b159fe2 100644 --- a/src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java +++ b/src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java @@ -1,27 +1,15 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; public class ValidParenthesesTest { - @Test - void testOne() { - assertTrue(ValidParentheses.isValid("()")); - assertTrue(ValidParentheses.isValidParentheses("()")); - } - - @Test - void testTwo() { - assertTrue(ValidParentheses.isValid("()[]{}")); - assertTrue(ValidParentheses.isValidParentheses("()[]{}")); - } - - @Test - void testThree() { - assertFalse(ValidParentheses.isValid("(]")); - assertFalse(ValidParentheses.isValidParentheses("(]")); + @ParameterizedTest(name = "Input: \"{0}\" → Expected: {1}") + @CsvSource({"'()', true", "'()[]{}', true", "'(]', false", "'{[]}', true", "'([{}])', true", "'([)]', false", "'', true", "'(', false", "')', false"}) + void testIsValid(String input, boolean expected) { + assertEquals(expected, ValidParentheses.isValid(input)); } } From 476898723afc510d9248eebdff297080d7edaacb Mon Sep 17 00:00:00 2001 From: Andrii Siriak Date: Tue, 8 Jul 2025 20:04:56 +0200 Subject: [PATCH 130/146] Update CODEOWNERS (#6353) --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8a0b18a54c0b..9a0617e18a06 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @DenizAltunkapan @yanglbme @vil02 @BamaCharanChhandogi @alxkm @siriak +* @DenizAltunkapan @yanglbme @vil02 @alxkm From c997a32018c6f876b6b4de96c765b1cc10ac1236 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Wed, 9 Jul 2025 21:36:39 +0300 Subject: [PATCH 131/146] refactor ShuffleArray: improve documentation and maintainability (#6357) refactor ShuffleArray: Improve Documentation and Code Quality --- .../com/thealgorithms/misc/ShuffleArray.java | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/misc/ShuffleArray.java b/src/main/java/com/thealgorithms/misc/ShuffleArray.java index 65d38adfc37a..e07c8df771d3 100644 --- a/src/main/java/com/thealgorithms/misc/ShuffleArray.java +++ b/src/main/java/com/thealgorithms/misc/ShuffleArray.java @@ -17,19 +17,37 @@ * @author Rashi Dashore (https://github.com/rashi07dashore) */ public final class ShuffleArray { - // Prevent instantiation + private ShuffleArray() { } /** - * This method shuffles an array using the Fisher-Yates algorithm. + * Shuffles the provided array in-place using the Fisher–Yates algorithm. * - * @param arr is the input array to be shuffled + * @param arr the array to shuffle; must not be {@code null} + * @throws IllegalArgumentException if the input array is {@code null} */ public static void shuffle(int[] arr) { + if (arr == null) { + throw new IllegalArgumentException("Input array must not be null"); + } + Random random = new Random(); for (int i = arr.length - 1; i > 0; i--) { int j = random.nextInt(i + 1); + swap(arr, i, j); + } + } + + /** + * Swaps two elements in an array. + * + * @param arr the array + * @param i index of first element + * @param j index of second element + */ + private static void swap(int[] arr, int i, int j) { + if (i != j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; From a6aadd5b642a59ce366cec53325313b6bf853bf3 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Wed, 9 Jul 2025 21:49:58 +0300 Subject: [PATCH 132/146] refactor: improve Sparsity class with input validation and clearer logic (#6351) Co-authored-by: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> --- .../java/com/thealgorithms/misc/Sparsity.java | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/thealgorithms/misc/Sparsity.java b/src/main/java/com/thealgorithms/misc/Sparsity.java index 08e50a121da4..4a919e0e55c6 100644 --- a/src/main/java/com/thealgorithms/misc/Sparsity.java +++ b/src/main/java/com/thealgorithms/misc/Sparsity.java @@ -1,40 +1,46 @@ package com.thealgorithms.misc; -/* - *A matrix is sparse if many of its coefficients are zero (In general if 2/3rd of matrix elements - *are 0, it is considered as sparse). The interest in sparsity arises because its exploitation can - *lead to enormous computational savings and because many large matrix problems that occur in - *practice are sparse. +/** + * Utility class for calculating the sparsity of a matrix. + * A matrix is considered sparse if a large proportion of its elements are zero. + * Typically, if more than 2/3 of the elements are zero, the matrix is considered sparse. * - * @author Ojasva Jain + * Sparsity is defined as: + * sparsity = (number of zero elements) / (total number of elements) + * + * This can lead to significant computational optimizations. */ +public final class Sparsity { -final class Sparsity { private Sparsity() { } - /* - * @param mat the input matrix - * @return Sparsity of matrix - * - * where sparsity = number of zeroes/total elements in matrix + /** + * Calculates the sparsity of a given 2D matrix. * + * @param matrix the input matrix + * @return the sparsity value between 0 and 1 + * @throws IllegalArgumentException if the matrix is null, empty, or contains empty rows */ - static double sparsity(double[][] mat) { - if (mat == null || mat.length == 0) { + public static double sparsity(double[][] matrix) { + if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { throw new IllegalArgumentException("Matrix cannot be null or empty"); } - int zero = 0; - // Traversing the matrix to count number of zeroes - for (int i = 0; i < mat.length; i++) { - for (int j = 0; j < mat[i].length; j++) { - if (mat[i][j] == 0) { - zero++; + int zeroCount = 0; + int totalElements = 0; + + // Count the number of zero elements and total elements + for (double[] row : matrix) { + for (double value : row) { + if (value == 0.0) { + zeroCount++; } + totalElements++; } } - // return sparsity - return ((double) zero / (mat.length * mat[0].length)); + + // Return sparsity as a double + return (double) zeroCount / totalElements; } } From 22cba2c84f510f40de922729528a1e886a084a80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Jul 2025 09:01:08 +0300 Subject: [PATCH 133/146] chore(deps): bump org.apache.commons:commons-lang3 from 3.17.0 to 3.18.0 (#6364) Bumps org.apache.commons:commons-lang3 from 3.17.0 to 3.18.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-lang3 dependency-version: 3.18.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ca2712d8c8ad..f5f1e0be12f7 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ org.apache.commons commons-lang3 - 3.17.0 + 3.18.0 org.apache.commons From f3252793e196cfaaad932b3d86fb4f3e26da1406 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Thu, 10 Jul 2025 18:52:38 +0300 Subject: [PATCH 134/146] refactor: refactor Alphabetical and AlphabeticalTest (#6355) --- .../thealgorithms/strings/Alphabetical.java | 28 ++++++++---------- .../strings/AlphabeticalTest.java | 29 +++++-------------- 2 files changed, 19 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/thealgorithms/strings/Alphabetical.java b/src/main/java/com/thealgorithms/strings/Alphabetical.java index de07dde2d510..ef2974eb427d 100644 --- a/src/main/java/com/thealgorithms/strings/Alphabetical.java +++ b/src/main/java/com/thealgorithms/strings/Alphabetical.java @@ -1,36 +1,32 @@ package com.thealgorithms.strings; /** + * Utility class for checking if a string's characters are in alphabetical order. + *

* Alphabetical order is a system whereby character strings are placed in order * based on the position of the characters in the conventional ordering of an - * alphabet. Wikipedia: https://en.wikipedia.org/wiki/Alphabetical_order + * alphabet. + *

+ * Reference: Wikipedia: Alphabetical Order */ -final class Alphabetical { +public final class Alphabetical { private Alphabetical() { } - public static void main(String[] args) { - assert !isAlphabetical("123abc"); - assert isAlphabetical("aBC"); - assert isAlphabetical("abc"); - assert !isAlphabetical("xyzabc"); - assert isAlphabetical("abcxyz"); - } - /** - * Check if a string is alphabetical order or not + * Checks whether the characters in the given string are in alphabetical order. + * Non-letter characters will cause the check to fail. * - * @param s a string - * @return {@code true} if given string is alphabetical order, otherwise - * {@code false} + * @param s the input string + * @return {@code true} if all characters are in alphabetical order (case-insensitive), otherwise {@code false} */ public static boolean isAlphabetical(String s) { s = s.toLowerCase(); for (int i = 0; i < s.length() - 1; ++i) { - if (!Character.isLetter(s.charAt(i)) || !(s.charAt(i) <= s.charAt(i + 1))) { + if (!Character.isLetter(s.charAt(i)) || s.charAt(i) > s.charAt(i + 1)) { return false; } } - return true; + return !s.isEmpty() && Character.isLetter(s.charAt(s.length() - 1)); } } diff --git a/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java b/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java index 083239152ec2..7b41e11ef22f 100644 --- a/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java +++ b/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java @@ -1,30 +1,15 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; public class AlphabeticalTest { - @Test - public void isAlphabetical() { - // expected to be true - String input1 = "abcdefghijklmno"; - String input2 = "abcdxxxyzzzz"; - String input3 = "fpw"; - - // expected to be false - String input4 = "123a"; - String input5 = "abcABC"; - String input6 = "abcdefghikjlmno"; - - assertTrue(Alphabetical.isAlphabetical(input1)); - assertTrue(Alphabetical.isAlphabetical(input2)); - assertTrue(Alphabetical.isAlphabetical(input3)); - - assertFalse(Alphabetical.isAlphabetical(input4)); - assertFalse(Alphabetical.isAlphabetical(input5)); - assertFalse(Alphabetical.isAlphabetical(input6)); + @ParameterizedTest(name = "\"{0}\" → Expected: {1}") + @CsvSource({"'abcdefghijklmno', true", "'abcdxxxyzzzz', true", "'123a', false", "'abcABC', false", "'abcdefghikjlmno', false", "'aBC', true", "'abc', true", "'xyzabc', false", "'abcxyz', true", "'', false", "'1', false"}) + void testIsAlphabetical(String input, boolean expected) { + assertEquals(expected, Alphabetical.isAlphabetical(input)); } } From 2ccc15671f68e8d9299c5f90067359174f76f6a1 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Fri, 11 Jul 2025 22:32:42 +0300 Subject: [PATCH 135/146] refactor: clean up LargestRectangle and convert tests to parameterized format (#6356) * refactor: clean up LargestRectangle and convert tests to parameterized format * refactor: fix clang formatting issue * refactor: fix clang formatting issue for test data --------- Co-authored-by: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> --- .../stacks/LargestRectangle.java | 50 +++++++----- .../stacks/LargestRectangleTest.java | 79 ++++--------------- 2 files changed, 47 insertions(+), 82 deletions(-) diff --git a/src/main/java/com/thealgorithms/stacks/LargestRectangle.java b/src/main/java/com/thealgorithms/stacks/LargestRectangle.java index 006e03632e63..eb222c8c488e 100644 --- a/src/main/java/com/thealgorithms/stacks/LargestRectangle.java +++ b/src/main/java/com/thealgorithms/stacks/LargestRectangle.java @@ -3,36 +3,50 @@ import java.util.Stack; /** + * Utility class to calculate the largest rectangle area in a histogram. + * Each bar's width is assumed to be 1 unit. * - * @author mohd rameez github.com/rameez471 + *

This implementation uses a monotonic stack to efficiently calculate + * the area of the largest rectangle that can be formed from the histogram bars.

+ * + *

Example usage: + *

{@code
+ *     int[] heights = {2, 1, 5, 6, 2, 3};
+ *     String area = LargestRectangle.largestRectangleHistogram(heights);
+ *     // area is "10"
+ * }
*/ - public final class LargestRectangle { + private LargestRectangle() { } + /** + * Calculates the largest rectangle area in the given histogram. + * + * @param heights an array of non-negative integers representing bar heights + * @return the largest rectangle area as a {@link String} + */ public static String largestRectangleHistogram(int[] heights) { - int n = heights.length; int maxArea = 0; - Stack st = new Stack<>(); - for (int i = 0; i < n; i++) { + Stack stack = new Stack<>(); + + for (int i = 0; i < heights.length; i++) { int start = i; - while (!st.isEmpty() && st.peek()[1] > heights[i]) { - int[] tmp = st.pop(); - maxArea = Math.max(maxArea, tmp[1] * (i - tmp[0])); - start = tmp[0]; + while (!stack.isEmpty() && stack.peek()[1] > heights[i]) { + int[] popped = stack.pop(); + maxArea = Math.max(maxArea, popped[1] * (i - popped[0])); + start = popped[0]; } - st.push(new int[] {start, heights[i]}); + stack.push(new int[] {start, heights[i]}); } - while (!st.isEmpty()) { - int[] tmp = st.pop(); - maxArea = Math.max(maxArea, tmp[1] * (n - tmp[0])); + + int totalLength = heights.length; + while (!stack.isEmpty()) { + int[] remaining = stack.pop(); + maxArea = Math.max(maxArea, remaining[1] * (totalLength - remaining[0])); } - return Integer.toString(maxArea); - } - public static void main(String[] args) { - assert largestRectangleHistogram(new int[] {2, 1, 5, 6, 2, 3}).equals("10"); - assert largestRectangleHistogram(new int[] {2, 4}).equals("4"); + return Integer.toString(maxArea); } } diff --git a/src/test/java/com/thealgorithms/stacks/LargestRectangleTest.java b/src/test/java/com/thealgorithms/stacks/LargestRectangleTest.java index a54372adda0e..fec5d371c106 100644 --- a/src/test/java/com/thealgorithms/stacks/LargestRectangleTest.java +++ b/src/test/java/com/thealgorithms/stacks/LargestRectangleTest.java @@ -2,76 +2,27 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; public class LargestRectangleTest { - @Test - void testLargestRectangleHistogramWithTypicalCases() { - // Typical case with mixed heights - int[] heights = {2, 1, 5, 6, 2, 3}; - String expected = "10"; - String result = LargestRectangle.largestRectangleHistogram(heights); - assertEquals(expected, result); - - // Another typical case with increasing heights - heights = new int[] {2, 4}; - expected = "4"; - result = LargestRectangle.largestRectangleHistogram(heights); - assertEquals(expected, result); - - // Case with multiple bars of the same height - heights = new int[] {4, 4, 4, 4}; - expected = "16"; - result = LargestRectangle.largestRectangleHistogram(heights); - assertEquals(expected, result); + @ParameterizedTest(name = "Histogram: {0} → Expected area: {1}") + @MethodSource("histogramProvider") + void testLargestRectangleHistogram(int[] heights, String expected) { + assertEquals(expected, LargestRectangle.largestRectangleHistogram(heights)); } - @Test - void testLargestRectangleHistogramWithEdgeCases() { - // Edge case with an empty array - int[] heights = {}; - String expected = "0"; - String result = LargestRectangle.largestRectangleHistogram(heights); - assertEquals(expected, result); - - // Edge case with a single bar - heights = new int[] {5}; - expected = "5"; - result = LargestRectangle.largestRectangleHistogram(heights); - assertEquals(expected, result); - - // Edge case with all bars of height 0 - heights = new int[] {0, 0, 0}; - expected = "0"; - result = LargestRectangle.largestRectangleHistogram(heights); - assertEquals(expected, result); + static Stream histogramProvider() { + return Stream.of(Arguments.of(new int[] {2, 1, 5, 6, 2, 3}, "10"), Arguments.of(new int[] {2, 4}, "4"), Arguments.of(new int[] {4, 4, 4, 4}, "16"), Arguments.of(new int[] {}, "0"), Arguments.of(new int[] {5}, "5"), Arguments.of(new int[] {0, 0, 0}, "0"), + Arguments.of(new int[] {6, 2, 5, 4, 5, 1, 6}, "12"), Arguments.of(new int[] {2, 1, 5, 6, 2, 3, 1}, "10"), Arguments.of(createLargeArray(10000, 1), "10000")); } - @Test - void testLargestRectangleHistogramWithLargeInput() { - // Large input case - int[] heights = new int[10000]; - for (int i = 0; i < heights.length; i++) { - heights[i] = 1; - } - String expected = "10000"; - String result = LargestRectangle.largestRectangleHistogram(heights); - assertEquals(expected, result); - } - - @Test - void testLargestRectangleHistogramWithComplexCases() { - // Complex case with a mix of heights - int[] heights = {6, 2, 5, 4, 5, 1, 6}; - String expected = "12"; - String result = LargestRectangle.largestRectangleHistogram(heights); - assertEquals(expected, result); - - // Case with a peak in the middle - heights = new int[] {2, 1, 5, 6, 2, 3, 1}; - expected = "10"; - result = LargestRectangle.largestRectangleHistogram(heights); - assertEquals(expected, result); + private static int[] createLargeArray(int size, int value) { + int[] arr = new int[size]; + java.util.Arrays.fill(arr, value); + return arr; } } From 3e0fd11a96e80baaa51a47b4ea4f45edeee261c0 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Fri, 11 Jul 2025 22:36:29 +0300 Subject: [PATCH 136/146] refactor: refactoring and documenting `Isomorphic String Checker` (#6359) refactor: refactoring and documenting Isomorphic String Checker Co-authored-by: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> --- .../com/thealgorithms/strings/Isomorphic.java | 43 +++++++++++++------ .../thealgorithms/strings/IsomorphicTest.java | 4 +- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/thealgorithms/strings/Isomorphic.java b/src/main/java/com/thealgorithms/strings/Isomorphic.java index ccd686170715..7ee00e62e16b 100644 --- a/src/main/java/com/thealgorithms/strings/Isomorphic.java +++ b/src/main/java/com/thealgorithms/strings/Isomorphic.java @@ -5,35 +5,54 @@ import java.util.Map; import java.util.Set; +/** + * Utility class to check if two strings are isomorphic. + * + *

+ * Two strings {@code s} and {@code t} are isomorphic if the characters in {@code s} + * can be replaced to get {@code t}, while preserving the order of characters. + * Each character must map to exactly one character, and no two characters can map to the same character. + *

+ * + * @see Isomorphic Strings + */ public final class Isomorphic { + private Isomorphic() { } - public static boolean checkStrings(String s, String t) { + /** + * Checks if two strings are isomorphic. + * + * @param s the first input string + * @param t the second input string + * @return {@code true} if {@code s} and {@code t} are isomorphic; {@code false} otherwise + */ + public static boolean areIsomorphic(String s, String t) { if (s.length() != t.length()) { return false; } - // To mark the characters of string using MAP - // character of first string as KEY and another as VALUE - // now check occurence by keeping the track with SET data structure - Map characterMap = new HashMap<>(); - Set trackUniqueCharacter = new HashSet<>(); + Map map = new HashMap<>(); + Set usedCharacters = new HashSet<>(); for (int i = 0; i < s.length(); i++) { - if (characterMap.containsKey(s.charAt(i))) { - if (t.charAt(i) != characterMap.get(s.charAt(i))) { + char sourceChar = s.charAt(i); + char targetChar = t.charAt(i); + + if (map.containsKey(sourceChar)) { + if (map.get(sourceChar) != targetChar) { return false; } } else { - if (trackUniqueCharacter.contains(t.charAt(i))) { + if (usedCharacters.contains(targetChar)) { return false; } - - characterMap.put(s.charAt(i), t.charAt(i)); + map.put(sourceChar, targetChar); + usedCharacters.add(targetChar); } - trackUniqueCharacter.add(t.charAt(i)); } + return true; } } diff --git a/src/test/java/com/thealgorithms/strings/IsomorphicTest.java b/src/test/java/com/thealgorithms/strings/IsomorphicTest.java index 4dd13fbc34ee..5c3ed89b65d3 100644 --- a/src/test/java/com/thealgorithms/strings/IsomorphicTest.java +++ b/src/test/java/com/thealgorithms/strings/IsomorphicTest.java @@ -12,8 +12,8 @@ public final class IsomorphicTest { @ParameterizedTest @MethodSource("inputs") public void testCheckStrings(String str1, String str2, Boolean expected) { - assertEquals(expected, Isomorphic.checkStrings(str1, str2)); - assertEquals(expected, Isomorphic.checkStrings(str2, str1)); + assertEquals(expected, Isomorphic.areIsomorphic(str1, str2)); + assertEquals(expected, Isomorphic.areIsomorphic(str2, str1)); } private static Stream inputs() { From 048bba9499f9844d30a0411d8b5552cae2cfcab8 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Fri, 11 Jul 2025 22:39:33 +0300 Subject: [PATCH 137/146] refactor: adding docs for `LongestCommonPrefixTest` and Parameterized Tests (#6360) * refactor: adding docs for LongestCommonPrefixTest and Parameterized Tests * checkstyle: fix clang formatting --------- Co-authored-by: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> --- .../strings/LongestCommonPrefix.java | 30 ++++++-- .../strings/LongestCommonPrefixTest.java | 75 ++++--------------- 2 files changed, 38 insertions(+), 67 deletions(-) diff --git a/src/main/java/com/thealgorithms/strings/LongestCommonPrefix.java b/src/main/java/com/thealgorithms/strings/LongestCommonPrefix.java index 0fabdaa2658b..3348b9cf860c 100644 --- a/src/main/java/com/thealgorithms/strings/LongestCommonPrefix.java +++ b/src/main/java/com/thealgorithms/strings/LongestCommonPrefix.java @@ -2,21 +2,41 @@ import java.util.Arrays; +/** + * Utility class for string operations. + *

+ * This class provides a method to find the longest common prefix (LCP) + * among an array of strings. + *

+ * + * @see Longest Common Prefix - Wikipedia + */ public final class LongestCommonPrefix { - public String longestCommonPrefix(String[] strs) { + + private LongestCommonPrefix() { + } + + /** + * Finds the longest common prefix among a list of strings using lexicographical sorting. + * The prefix is common to the first and last elements after sorting the array. + * + * @param strs array of input strings + * @return the longest common prefix, or empty string if none exists + */ + public static String longestCommonPrefix(String[] strs) { if (strs == null || strs.length == 0) { return ""; } Arrays.sort(strs); - String shortest = strs[0]; - String longest = strs[strs.length - 1]; + String first = strs[0]; + String last = strs[strs.length - 1]; int index = 0; - while (index < shortest.length() && index < longest.length() && shortest.charAt(index) == longest.charAt(index)) { + while (index < first.length() && index < last.length() && first.charAt(index) == last.charAt(index)) { index++; } - return shortest.substring(0, index); + return first.substring(0, index); } } diff --git a/src/test/java/com/thealgorithms/strings/LongestCommonPrefixTest.java b/src/test/java/com/thealgorithms/strings/LongestCommonPrefixTest.java index 580a2726d285..84e54f75e8cb 100644 --- a/src/test/java/com/thealgorithms/strings/LongestCommonPrefixTest.java +++ b/src/test/java/com/thealgorithms/strings/LongestCommonPrefixTest.java @@ -2,72 +2,23 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; +import java.util.stream.Stream; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; public class LongestCommonPrefixTest { - private final LongestCommonPrefix longestCommonPrefix = new LongestCommonPrefix(); - - @Test - public void testCommonPrefix() { - String[] input = {"flower", "flow", "flight"}; - String expected = "fl"; - assertEquals(expected, longestCommonPrefix.longestCommonPrefix(input)); - } - - @Test - public void testNoCommonPrefix() { - String[] input = {"dog", "racecar", "car"}; - String expected = ""; - assertEquals(expected, longestCommonPrefix.longestCommonPrefix(input)); - } - - @Test - public void testEmptyArray() { - String[] input = {}; - String expected = ""; - assertEquals(expected, longestCommonPrefix.longestCommonPrefix(input)); - } - - @Test - public void testNullArray() { - String[] input = null; - String expected = ""; - assertEquals(expected, longestCommonPrefix.longestCommonPrefix(input)); - } - - @Test - public void testSingleString() { - String[] input = {"single"}; - String expected = "single"; - assertEquals(expected, longestCommonPrefix.longestCommonPrefix(input)); - } - - @Test - public void testCommonPrefixWithDifferentLengths() { - String[] input = {"ab", "a"}; - String expected = "a"; - assertEquals(expected, longestCommonPrefix.longestCommonPrefix(input)); - } - - @Test - public void testAllSameStrings() { - String[] input = {"test", "test", "test"}; - String expected = "test"; - assertEquals(expected, longestCommonPrefix.longestCommonPrefix(input)); - } - - @Test - public void testPrefixAtEnd() { - String[] input = {"abcde", "abcfgh", "abcmnop"}; - String expected = "abc"; - assertEquals(expected, longestCommonPrefix.longestCommonPrefix(input)); + @ParameterizedTest(name = "{index} => input={0}, expected=\"{1}\"") + @MethodSource("provideTestCases") + @DisplayName("Test Longest Common Prefix") + void testLongestCommonPrefix(String[] input, String expected) { + assertEquals(expected, LongestCommonPrefix.longestCommonPrefix(input)); } - @Test - public void testMixedCase() { - String[] input = {"Flower", "flow", "flight"}; - String expected = ""; - assertEquals(expected, longestCommonPrefix.longestCommonPrefix(input)); + private static Stream provideTestCases() { + return Stream.of(Arguments.of(new String[] {"flower", "flow", "flight"}, "fl"), Arguments.of(new String[] {"dog", "racecar", "car"}, ""), Arguments.of(new String[] {}, ""), Arguments.of(null, ""), Arguments.of(new String[] {"single"}, "single"), Arguments.of(new String[] {"ab", "a"}, "a"), + Arguments.of(new String[] {"test", "test", "test"}, "test"), Arguments.of(new String[] {"abcde", "abcfgh", "abcmnop"}, "abc"), Arguments.of(new String[] {"Flower", "flow", "flight"}, "")); } } From 0a4f5542d932037dbbd071117477c2cbdec6bb41 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Fri, 11 Jul 2025 22:42:45 +0300 Subject: [PATCH 138/146] cleanup: Improve docs, safety, and readability in `RangeInSortedArray` (#6361) * cleanup: Improve docs, safety, and readability in RangeInSortedArray * formatting: fix comment formatting issue * formatting: fix array formatting issue --------- Co-authored-by: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> --- .../misc/RangeInSortedArray.java | 78 +++++++++++++++---- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java b/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java index 6d3caa1814b6..0ae73dd73f09 100644 --- a/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java +++ b/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java @@ -1,25 +1,46 @@ package com.thealgorithms.misc; +/** + * Utility class for operations to find the range of occurrences of a key + * in a sorted (non-decreasing) array, and to count elements less than or equal to a given key. + */ public final class RangeInSortedArray { + private RangeInSortedArray() { } - // Get the 1st and last occurrence index of a number 'key' in a non-decreasing array 'nums' - // Gives [-1, -1] in case element doesn't exist in array + /** + * Finds the first and last occurrence indices of the key in a sorted array. + * + * @param nums sorted array of integers (non-decreasing order) + * @param key the target value to search for + * @return int array of size two where + * - index 0 is the first occurrence of key, + * - index 1 is the last occurrence of key, + * or [-1, -1] if the key does not exist in the array. + */ public static int[] sortedRange(int[] nums, int key) { int[] range = new int[] {-1, -1}; - alteredBinSearchIter(nums, key, 0, nums.length - 1, range, true); - alteredBinSearchIter(nums, key, 0, nums.length - 1, range, false); + alteredBinSearchIter(nums, key, 0, nums.length - 1, range, true); // find left boundary + alteredBinSearchIter(nums, key, 0, nums.length - 1, range, false); // find right boundary return range; } - // Recursive altered binary search which searches for leftmost as well as rightmost occurrence - // of 'key' + /** + * Recursive altered binary search to find either the leftmost or rightmost occurrence of a key. + * + * @param nums the sorted array + * @param key the target to find + * @param left current left bound in search + * @param right current right bound in search + * @param range array to update with boundaries: range[0] for leftmost, range[1] for rightmost + * @param goLeft if true, searches for leftmost occurrence; if false, for rightmost occurrence + */ public static void alteredBinSearch(int[] nums, int key, int left, int right, int[] range, boolean goLeft) { if (left > right) { return; } - int mid = (left + right) >>> 1; + int mid = left + ((right - left) >>> 1); if (nums[mid] > key) { alteredBinSearch(nums, key, left, mid - 1, range, goLeft); } else if (nums[mid] < key) { @@ -41,11 +62,19 @@ public static void alteredBinSearch(int[] nums, int key, int left, int right, in } } - // Iterative altered binary search which searches for leftmost as well as rightmost occurrence - // of 'key' + /** + * Iterative altered binary search to find either the leftmost or rightmost occurrence of a key. + * + * @param nums the sorted array + * @param key the target to find + * @param left initial left bound + * @param right initial right bound + * @param range array to update with boundaries: range[0] for leftmost, range[1] for rightmost + * @param goLeft if true, searches for leftmost occurrence; if false, for rightmost occurrence + */ public static void alteredBinSearchIter(int[] nums, int key, int left, int right, int[] range, boolean goLeft) { while (left <= right) { - final int mid = (left + right) >>> 1; + int mid = left + ((right - left) >>> 1); if (nums[mid] > key) { right = mid - 1; } else if (nums[mid] < key) { @@ -55,33 +84,48 @@ public static void alteredBinSearchIter(int[] nums, int key, int left, int right if (mid == 0 || nums[mid - 1] != key) { range[0] = mid; return; - } else { - right = mid - 1; } + right = mid - 1; } else { if (mid == nums.length - 1 || nums[mid + 1] != key) { range[1] = mid; return; - } else { - left = mid + 1; } + left = mid + 1; } } } } + /** + * Counts the number of elements strictly less than the given key. + * + * @param nums sorted array + * @param key the key to compare + * @return the count of elements less than the key + */ public static int getCountLessThan(int[] nums, int key) { return getLessThan(nums, key, 0, nums.length - 1); } + /** + * Helper method using binary search to count elements less than or equal to the key. + * + * @param nums sorted array + * @param key the key to compare + * @param left current left bound + * @param right current right bound + * @return count of elements less than or equal to the key + */ public static int getLessThan(int[] nums, int key, int left, int right) { int count = 0; while (left <= right) { - final int mid = (left + right) >>> 1; + int mid = left + ((right - left) >>> 1); if (nums[mid] > key) { right = mid - 1; - } else if (nums[mid] <= key) { - count = mid + 1; // At least mid+1 elements exist which are <= key + } else { + // nums[mid] <= key + count = mid + 1; // all elements from 0 to mid inclusive are <= key left = mid + 1; } } From acb4753d65ce960222bf37ba3ae38cbb59cd8ed5 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Sat, 12 Jul 2025 09:44:57 +0300 Subject: [PATCH 139/146] refactor: Improve readability and code clarity in `InfixToPostfix` (#6362) refactor: improve InfixToPostfix Co-authored-by: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> --- .../thealgorithms/stacks/InfixToPostfix.java | 100 +++++++++++++----- .../stacks/InfixToPostfixTest.java | 4 +- 2 files changed, 73 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java b/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java index 33611bd73dba..77ca3e70849f 100644 --- a/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java +++ b/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java @@ -4,54 +4,96 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * Utility class for converting an infix arithmetic expression + * into its equivalent postfix (Reverse Polish Notation) form. + *

+ * This class provides a static method to perform the conversion, + * validating balanced brackets before processing. + *

+ */ public final class InfixToPostfix { + private InfixToPostfix() { } - public static String infix2PostFix(String infixExpression) throws Exception { + /** + * Converts a given infix expression string to a postfix expression string. + *

+ * The method first checks if the brackets in the input expression are balanced + * by calling {@code BalancedBrackets.isBalanced} on the filtered brackets. + * If the brackets are not balanced, it throws an IllegalArgumentException. + *

+ *

+ * Supported operators are: {@code +, -, *, /, ^} + * and operands can be letters or digits. + *

+ * + * @param infixExpression the arithmetic expression in infix notation + * @return the equivalent postfix notation expression + * @throws IllegalArgumentException if the brackets in the expression are unbalanced + */ + public static String infix2PostFix(String infixExpression) { if (!BalancedBrackets.isBalanced(filterBrackets(infixExpression))) { - throw new Exception("invalid expression"); + throw new IllegalArgumentException("Invalid expression: unbalanced brackets."); } + StringBuilder output = new StringBuilder(); - Stack stack = new Stack<>(); - for (char element : infixExpression.toCharArray()) { - if (Character.isLetterOrDigit(element)) { - output.append(element); - } else if (element == '(') { - stack.push(element); - } else if (element == ')') { - while (!stack.isEmpty() && stack.peek() != '(') { - output.append(stack.pop()); + Stack operatorStack = new Stack<>(); + + for (char token : infixExpression.toCharArray()) { + if (Character.isLetterOrDigit(token)) { + // Append operands (letters or digits) directly to output + output.append(token); + } else if (token == '(') { + // Push '(' to stack + operatorStack.push(token); + } else if (token == ')') { + // Pop and append until '(' is found + while (!operatorStack.isEmpty() && operatorStack.peek() != '(') { + output.append(operatorStack.pop()); } - stack.pop(); + operatorStack.pop(); // Remove '(' from stack } else { - while (!stack.isEmpty() && precedence(element) <= precedence(stack.peek())) { - output.append(stack.pop()); + // Pop operators with higher or equal precedence and append them + while (!operatorStack.isEmpty() && precedence(token) <= precedence(operatorStack.peek())) { + output.append(operatorStack.pop()); } - stack.push(element); + operatorStack.push(token); } } - while (!stack.isEmpty()) { - output.append(stack.pop()); + + // Pop any remaining operators + while (!operatorStack.isEmpty()) { + output.append(operatorStack.pop()); } + return output.toString(); } + /** + * Returns the precedence level of the given operator. + * + * @param operator the operator character (e.g., '+', '-', '*', '/', '^') + * @return the precedence value: higher means higher precedence, + * or -1 if the character is not a recognized operator + */ private static int precedence(char operator) { - switch (operator) { - case '+': - case '-': - return 0; - case '*': - case '/': - return 1; - case '^': - return 2; - default: - return -1; - } + return switch (operator) { + case '+', '-' -> 0; + case '*', '/' -> 1; + case '^' -> 2; + default -> -1; + }; } + /** + * Extracts only the bracket characters from the input string. + * Supports parentheses (), curly braces {}, square brackets [], and angle brackets <>. + * + * @param input the original expression string + * @return a string containing only bracket characters from the input + */ private static String filterBrackets(String input) { Pattern pattern = Pattern.compile("[^(){}\\[\\]<>]"); Matcher matcher = pattern.matcher(input); diff --git a/src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java b/src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java index 02a08e393a00..bd63c1ac28f2 100644 --- a/src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java +++ b/src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java @@ -12,7 +12,7 @@ class InfixToPostfixTest { @ParameterizedTest @MethodSource("provideValidExpressions") - void testValidExpressions(String infix, String expectedPostfix) throws Exception { + void testValidExpressions(String infix, String expectedPostfix) { assertEquals(expectedPostfix, InfixToPostfix.infix2PostFix(infix)); } @@ -28,6 +28,6 @@ void testInvalidExpressions(String infix, String expectedMessage) { } private static Stream provideInvalidExpressions() { - return Stream.of(Arguments.of("((a+b)*c-d", "invalid expression")); + return Stream.of(Arguments.of("((a+b)*c-d", "Invalid expression: unbalanced brackets.")); } } From 7590d8234f236729bafe4e5c826fb3eaff5d6444 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Sat, 12 Jul 2025 09:47:49 +0300 Subject: [PATCH 140/146] refactor: add JavaDocs and improve readability in `InfixToPrefix` (#6363) * refactor: add JavaDocs and improve readability in InfixToPrefix * formatting: remove redundant newline --------- Co-authored-by: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> --- .../thealgorithms/stacks/InfixToPrefix.java | 106 +++++++++++------- .../stacks/InfixToPrefixTest.java | 2 +- 2 files changed, 66 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/thealgorithms/stacks/InfixToPrefix.java b/src/main/java/com/thealgorithms/stacks/InfixToPrefix.java index 3d90d14e0d1e..e9ee5e208df6 100644 --- a/src/main/java/com/thealgorithms/stacks/InfixToPrefix.java +++ b/src/main/java/com/thealgorithms/stacks/InfixToPrefix.java @@ -4,85 +4,109 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * Utility class for converting an infix arithmetic expression + * into its equivalent prefix notation expression. + *

+ * This class provides a static method to perform the conversion, + * validating balanced brackets before processing. + *

+ */ public final class InfixToPrefix { + private InfixToPrefix() { } /** - * Convert an infix expression to a prefix expression using stack. + * Converts a given infix expression string to a prefix expression string. + *

+ * The method validates that the input expression has balanced brackets using + * {@code BalancedBrackets.isBalanced} on the filtered bracket characters. + * It throws an {@code IllegalArgumentException} if the brackets are unbalanced, + * and a {@code NullPointerException} if the input is null. + *

+ *

+ * Supported operators: {@code +, -, *, /, ^} and operands can be letters or digits. + *

* - * @param infixExpression the infix expression to convert - * @return the prefix expression - * @throws IllegalArgumentException if the infix expression has unbalanced brackets - * @throws NullPointerException if the infix expression is null + * @param infixExpression the arithmetic expression in infix notation + * @return the equivalent prefix notation expression + * @throws IllegalArgumentException if brackets are unbalanced + * @throws NullPointerException if the input expression is null */ - public static String infix2Prefix(String infixExpression) throws IllegalArgumentException { + public static String infix2Prefix(String infixExpression) { if (infixExpression == null) { throw new NullPointerException("Input expression cannot be null."); } + infixExpression = infixExpression.trim(); if (infixExpression.isEmpty()) { return ""; } + if (!BalancedBrackets.isBalanced(filterBrackets(infixExpression))) { throw new IllegalArgumentException("Invalid expression: unbalanced brackets."); } StringBuilder output = new StringBuilder(); - Stack stack = new Stack<>(); - // Reverse the infix expression for prefix conversion + Stack operatorStack = new Stack<>(); + + // Reverse the infix expression to facilitate prefix conversion String reversedInfix = new StringBuilder(infixExpression).reverse().toString(); - for (char element : reversedInfix.toCharArray()) { - if (Character.isLetterOrDigit(element)) { - output.append(element); - } else if (element == ')') { - stack.push(element); - } else if (element == '(') { - while (!stack.isEmpty() && stack.peek() != ')') { - output.append(stack.pop()); + + for (char token : reversedInfix.toCharArray()) { + if (Character.isLetterOrDigit(token)) { + // Append operands directly to output + output.append(token); + } else if (token == ')') { + // Push ')' onto stack (since expression is reversed, '(' and ')' roles swapped) + operatorStack.push(token); + } else if (token == '(') { + // Pop operators until ')' is found + while (!operatorStack.isEmpty() && operatorStack.peek() != ')') { + output.append(operatorStack.pop()); } - stack.pop(); + operatorStack.pop(); // Remove the ')' } else { - while (!stack.isEmpty() && precedence(element) < precedence(stack.peek())) { - output.append(stack.pop()); + // Pop operators with higher precedence before pushing current operator + while (!operatorStack.isEmpty() && precedence(token) < precedence(operatorStack.peek())) { + output.append(operatorStack.pop()); } - stack.push(element); + operatorStack.push(token); } } - while (!stack.isEmpty()) { - output.append(stack.pop()); + + // Append any remaining operators in stack + while (!operatorStack.isEmpty()) { + output.append(operatorStack.pop()); } - // Reverse the result to get the prefix expression + // Reverse the output to obtain the final prefix expression return output.reverse().toString(); } /** - * Determines the precedence of an operator. + * Returns the precedence level of the given operator. * - * @param operator the operator whose precedence is to be determined - * @return the precedence of the operator + * @param operator the operator character (e.g., '+', '-', '*', '/', '^') + * @return the precedence value: higher means higher precedence, + * or -1 if the character is not a recognized operator */ private static int precedence(char operator) { - switch (operator) { - case '+': - case '-': - return 0; - case '*': - case '/': - return 1; - case '^': - return 2; - default: - return -1; - } + return switch (operator) { + case '+', '-' -> 0; + case '*', '/' -> 1; + case '^' -> 2; + default -> -1; + }; } /** - * Filters out all characters from the input string except brackets. + * Extracts only the bracket characters from the input string. + * Supports parentheses (), curly braces {}, square brackets [], and angle brackets <>. * - * @param input the input string to filter - * @return a string containing only brackets from the input string + * @param input the original expression string + * @return a string containing only bracket characters from the input */ private static String filterBrackets(String input) { Pattern pattern = Pattern.compile("[^(){}\\[\\]<>]"); diff --git a/src/test/java/com/thealgorithms/stacks/InfixToPrefixTest.java b/src/test/java/com/thealgorithms/stacks/InfixToPrefixTest.java index 91be8a63da62..0ea948307336 100644 --- a/src/test/java/com/thealgorithms/stacks/InfixToPrefixTest.java +++ b/src/test/java/com/thealgorithms/stacks/InfixToPrefixTest.java @@ -13,7 +13,7 @@ public class InfixToPrefixTest { @ParameterizedTest @MethodSource("provideValidExpressions") - void testValidExpressions(String infix, String expectedPrefix) throws Exception { + void testValidExpressions(String infix, String expectedPrefix) { assertEquals(expectedPrefix, InfixToPrefix.infix2Prefix(infix)); } From dba2d869f2f39ecdf7e036c6130f05dbe1377fb6 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Sat, 12 Jul 2025 09:51:49 +0300 Subject: [PATCH 141/146] refactor: improving `GenericRoot` (#6365) refactor: improving GenericRoot --- .../com/thealgorithms/maths/GenericRoot.java | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/GenericRoot.java b/src/main/java/com/thealgorithms/maths/GenericRoot.java index 07f4756f93f8..e13efe5a77e0 100644 --- a/src/main/java/com/thealgorithms/maths/GenericRoot.java +++ b/src/main/java/com/thealgorithms/maths/GenericRoot.java @@ -1,30 +1,48 @@ package com.thealgorithms.maths; -/* - * Algorithm explanation: - * https://technotip.com/6774/c-program-to-find-generic-root-of-a-number/#:~:text=Generic%20Root%3A%20of%20a%20number,get%20a%20single%2Ddigit%20output.&text=For%20Example%3A%20If%20user%20input,%2B%204%20%2B%205%20%3D%2015. +/** + * Calculates the generic root (repeated digital sum) of a non-negative integer. + *

+ * For example, the generic root of 12345 is calculated as: + * 1 + 2 + 3 + 4 + 5 = 15, + * then 1 + 5 = 6, so the generic root is 6. + *

+ * Reference: + * https://technotip.com/6774/c-program-to-find-generic-root-of-a-number/ */ public final class GenericRoot { + + private static final int BASE = 10; + private GenericRoot() { } - private static int base = 10; - + /** + * Computes the sum of the digits of a non-negative integer in base 10. + * + * @param n non-negative integer + * @return sum of digits of {@code n} + */ private static int sumOfDigits(final int n) { assert n >= 0; - if (n < base) { + if (n < BASE) { return n; } - return n % base + sumOfDigits(n / base); + return (n % BASE) + sumOfDigits(n / BASE); } + /** + * Computes the generic root (repeated digital sum) of an integer. + * For negative inputs, the absolute value is used. + * + * @param n integer input + * @return generic root of {@code n} + */ public static int genericRoot(final int n) { - if (n < 0) { - return genericRoot(-n); - } - if (n > base) { - return genericRoot(sumOfDigits(n)); + int number = Math.abs(n); + if (number < BASE) { + return number; } - return n; + return genericRoot(sumOfDigits(number)); } } From 910d5b880ad6187ffdf504732c9fc4baed3ef371 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Sun, 13 Jul 2025 12:11:57 +0300 Subject: [PATCH 142/146] refactor: Refactor `SJFScheduling` and Tests (#6372) * refactor: Refactor SJFScheduling and Tests * refactor: fix checkstyle * refactor: add full imports * refactor: add full imports * refactor: remove redundant newline * refactor: fix indexed list iteration --- .../scheduling/SJFScheduling.java | 109 +++++++--------- .../scheduling/SJFSchedulingTest.java | 117 +++++------------- 2 files changed, 71 insertions(+), 155 deletions(-) diff --git a/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java b/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java index cbbc65a3afc5..e3f4a8d03d07 100644 --- a/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java +++ b/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java @@ -2,78 +2,62 @@ import com.thealgorithms.devutils.entities.ProcessDetails; import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; import java.util.List; /** - * Implementation of Shortest Job First Algorithm: The algorithm allows the waiting process with the - * minimal burst time to be executed first. see more here: - * https://www.guru99.com/shortest-job-first-sjf-scheduling.html + * Shortest Job First (SJF) Scheduling Algorithm: + * Executes processes with the shortest burst time first among the ones that have arrived. */ - public class SJFScheduling { - protected ArrayList processes; - protected ArrayList schedule; - - private static void sortProcessesByArrivalTime(List processes) { - for (int i = 0; i < processes.size(); i++) { - for (int j = i + 1; j < processes.size() - 1; j++) { - if (processes.get(j).getArrivalTime() > processes.get(j + 1).getArrivalTime()) { - final var temp = processes.get(j); - processes.set(j, processes.get(j + 1)); - processes.set(j + 1, temp); - } - } - } - } + private final List processes; + private final List schedule; - /** - * a simple constructor - * @param processes a list of processes the user wants to schedule - * it also sorts the processes based on the time of their arrival - */ - SJFScheduling(final ArrayList processes) { - this.processes = processes; - schedule = new ArrayList<>(); + public SJFScheduling(final List processes) { + this.processes = new ArrayList<>(processes); + this.schedule = new ArrayList<>(); sortProcessesByArrivalTime(this.processes); } - protected void sortByArrivalTime() { - sortProcessesByArrivalTime(processes); + + private static void sortProcessesByArrivalTime(List processes) { + processes.sort(Comparator.comparingInt(ProcessDetails::getArrivalTime)); } /** - * this functions returns the order of the executions + * Executes the SJF scheduling algorithm and builds the execution order. */ - public void scheduleProcesses() { - ArrayList ready = new ArrayList<>(); - + List ready = new ArrayList<>(); int size = processes.size(); - int runtime; int time = 0; int executed = 0; - int j; - int k = 0; - ProcessDetails running; - if (size == 0) { - return; + Iterator processIterator = processes.iterator(); + + // This will track the next process to be checked for arrival time + ProcessDetails nextProcess = null; + if (processIterator.hasNext()) { + nextProcess = processIterator.next(); } while (executed < size) { - while (k < size && processes.get(k).getArrivalTime() <= time) // here we find the processes that have arrived. - { - ready.add(processes.get(k)); - k++; + // Load all processes that have arrived by current time + while (nextProcess != null && nextProcess.getArrivalTime() <= time) { + ready.add(nextProcess); + if (processIterator.hasNext()) { + nextProcess = processIterator.next(); + } else { + nextProcess = null; + } } - running = findShortestJob(ready); + ProcessDetails running = findShortestJob(ready); if (running == null) { time++; } else { - runtime = running.getBurstTime(); - for (j = 0; j < runtime; j++) { - time++; - } + time += running.getBurstTime(); schedule.add(running.getProcessId()); ready.remove(running); executed++; @@ -82,30 +66,23 @@ public void scheduleProcesses() { } /** - * this function evaluates the shortest job of all the ready processes (based on a process - * burst time) + * Finds the process with the shortest job of all the ready processes (based on a process * @param readyProcesses an array list of ready processes * @return returns the process' with the shortest burst time OR NULL if there are no ready * processes */ - private ProcessDetails findShortestJob(List readyProcesses) { - if (readyProcesses.isEmpty()) { - return null; - } - int i; - int size = readyProcesses.size(); - int minBurstTime = readyProcesses.get(0).getBurstTime(); - int temp; - int positionOfShortestJob = 0; + private ProcessDetails findShortestJob(Collection readyProcesses) { + return readyProcesses.stream().min(Comparator.comparingInt(ProcessDetails::getBurstTime)).orElse(null); + } - for (i = 1; i < size; i++) { - temp = readyProcesses.get(i).getBurstTime(); - if (minBurstTime > temp) { - minBurstTime = temp; - positionOfShortestJob = i; - } - } + /** + * Returns the computed schedule after calling scheduleProcesses(). + */ + public List getSchedule() { + return schedule; + } - return readyProcesses.get(positionOfShortestJob); + public List getProcesses() { + return List.copyOf(processes); } } diff --git a/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java index aab5c64c847f..660a53299ab0 100644 --- a/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java +++ b/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java @@ -4,107 +4,46 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import com.thealgorithms.devutils.entities.ProcessDetails; -import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; class SJFSchedulingTest { - private ArrayList process; - void initialisation0() { - process = new ArrayList<>(); - process.add(new ProcessDetails("1", 0, 6)); - process.add(new ProcessDetails("2", 1, 2)); + private static Stream schedulingTestData() { + return Stream.of(Arguments.of(List.of(new ProcessDetails("1", 0, 6), new ProcessDetails("2", 1, 2)), List.of("1", "2")), + Arguments.of(List.of(new ProcessDetails("1", 0, 6), new ProcessDetails("2", 1, 2), new ProcessDetails("3", 4, 3), new ProcessDetails("4", 3, 1), new ProcessDetails("5", 6, 4), new ProcessDetails("6", 5, 5)), List.of("1", "4", "2", "3", "5", "6")), + Arguments.of(List.of(new ProcessDetails("1", 0, 3), new ProcessDetails("2", 1, 2), new ProcessDetails("3", 2, 1)), List.of("1", "3", "2")), Arguments.of(List.of(new ProcessDetails("1", 0, 3), new ProcessDetails("2", 5, 2), new ProcessDetails("3", 9, 1)), List.of("1", "2", "3")), + Arguments.of(Collections.emptyList(), List.of())); } - void initialisation1() { - process = new ArrayList<>(); - process.add(new ProcessDetails("1", 0, 6)); - process.add(new ProcessDetails("2", 1, 2)); - process.add(new ProcessDetails("3", 4, 3)); - process.add(new ProcessDetails("4", 3, 1)); - process.add(new ProcessDetails("5", 6, 4)); - process.add(new ProcessDetails("6", 5, 5)); - } - - void initialisation2() { - - process = new ArrayList<>(); - process.add(new ProcessDetails("1", 0, 3)); - process.add(new ProcessDetails("2", 1, 2)); - process.add(new ProcessDetails("3", 2, 1)); - } - void initialisation3() { - process = new ArrayList<>(); - process.add(new ProcessDetails("1", 0, 3)); - process.add(new ProcessDetails("2", 5, 2)); - process.add(new ProcessDetails("3", 9, 1)); - } - @Test - void constructor() { - initialisation0(); - SJFScheduling a = new SJFScheduling(process); - assertEquals(6, a.processes.get(0).getBurstTime()); - assertEquals(2, a.processes.get(1).getBurstTime()); + @ParameterizedTest(name = "Test SJF schedule: {index}") + @MethodSource("schedulingTestData") + void testSJFScheduling(List inputProcesses, List expectedSchedule) { + SJFScheduling scheduler = new SJFScheduling(inputProcesses); + scheduler.scheduleProcesses(); + assertEquals(expectedSchedule, scheduler.getSchedule()); } @Test - void sort() { - initialisation1(); - SJFScheduling a = new SJFScheduling(process); - a.sortByArrivalTime(); - assertEquals("1", a.processes.get(0).getProcessId()); - assertEquals("2", a.processes.get(1).getProcessId()); - assertEquals("3", a.processes.get(3).getProcessId()); - assertEquals("4", a.processes.get(2).getProcessId()); - assertEquals("5", a.processes.get(5).getProcessId()); - assertEquals("6", a.processes.get(4).getProcessId()); - } + @DisplayName("Test sorting by arrival order") + void testProcessArrivalOrderIsSorted() { + List processes = List.of(new ProcessDetails("1", 0, 6), new ProcessDetails("2", 1, 2), new ProcessDetails("4", 3, 1), new ProcessDetails("3", 4, 3), new ProcessDetails("6", 5, 5), new ProcessDetails("5", 6, 4)); + SJFScheduling scheduler = new SJFScheduling(processes); + List actualOrder = scheduler.getProcesses().stream().map(ProcessDetails::getProcessId).toList(); - @Test - void scheduling() { - initialisation1(); - SJFScheduling a = new SJFScheduling(process); - a.scheduleProcesses(); - assertEquals("1", a.schedule.get(0)); - assertEquals("4", a.schedule.get(1)); - assertEquals("2", a.schedule.get(2)); - assertEquals("3", a.schedule.get(3)); - assertEquals("5", a.schedule.get(4)); - assertEquals("6", a.schedule.get(5)); + assertEquals(List.of("1", "2", "4", "3", "6", "5"), actualOrder); } @Test - void schedulingOfTwoProcesses() { - initialisation0(); - SJFScheduling a = new SJFScheduling(process); - a.scheduleProcesses(); - assertEquals("1", a.schedule.get(0)); - assertEquals("2", a.schedule.get(1)); - } - - @Test - void schedulingOfAShortestJobArrivingLast() { - initialisation2(); - SJFScheduling a = new SJFScheduling(process); - a.scheduleProcesses(); - assertEquals("1", a.schedule.get(0)); - assertEquals("3", a.schedule.get(1)); - assertEquals("2", a.schedule.get(2)); - } - @Test - void schedulingWithProcessesNotComingBackToBack() { - initialisation3(); - SJFScheduling a = new SJFScheduling(process); - a.scheduleProcesses(); - assertEquals("1", a.schedule.get(0)); - assertEquals("2", a.schedule.get(1)); - assertEquals("3", a.schedule.get(2)); - } - @Test - void schedulingOfNothing() { - process = new ArrayList<>(); - SJFScheduling a = new SJFScheduling(process); - a.scheduleProcesses(); - assertTrue(a.schedule.isEmpty()); + void testSchedulingEmptyList() { + SJFScheduling scheduler = new SJFScheduling(Collections.emptyList()); + scheduler.scheduleProcesses(); + assertTrue(scheduler.getSchedule().isEmpty()); } } From 182118b6a44bd482e6c14b662b63fcd068dae9cb Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Sun, 13 Jul 2025 12:17:38 +0300 Subject: [PATCH 143/146] refactor: cleanup `GenerateSubsets` (#6373) refactor: cleanup GenerateSubsets Co-authored-by: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> --- .../recursion/GenerateSubsets.java | 50 ++++++++++++------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/thealgorithms/recursion/GenerateSubsets.java b/src/main/java/com/thealgorithms/recursion/GenerateSubsets.java index 5a3ff2e88040..0114a55e5b75 100644 --- a/src/main/java/com/thealgorithms/recursion/GenerateSubsets.java +++ b/src/main/java/com/thealgorithms/recursion/GenerateSubsets.java @@ -1,36 +1,52 @@ package com.thealgorithms.recursion; -// program to find power set of a string - import java.util.ArrayList; import java.util.List; +/** + * Utility class to generate all subsets (power set) of a given string using recursion. + * + *

For example, the string "ab" will produce: ["ab", "a", "b", ""] + */ public final class GenerateSubsets { private GenerateSubsets() { - throw new UnsupportedOperationException("Utility class"); } + /** + * Generates all subsets (power set) of the given string using recursion. + * + * @param str the input string to generate subsets for + * @return a list of all subsets of the input string + */ public static List subsetRecursion(String str) { - return doRecursion("", str); + return generateSubsets("", str); } - private static List doRecursion(String p, String up) { - if (up.isEmpty()) { - List list = new ArrayList<>(); - list.add(p); - return list; + /** + * Recursive helper method to generate subsets by including or excluding characters. + * + * @param current the current prefix being built + * @param remaining the remaining string to process + * @return list of subsets formed from current and remaining + */ + private static List generateSubsets(String current, String remaining) { + if (remaining.isEmpty()) { + List result = new ArrayList<>(); + result.add(current); + return result; } - // Taking the character - char ch = up.charAt(0); - // Adding the character in the recursion - List left = doRecursion(p + ch, up.substring(1)); - // Not adding the character in the recursion - List right = doRecursion(p, up.substring(1)); + char ch = remaining.charAt(0); + String next = remaining.substring(1); + + // Include the character + List withChar = generateSubsets(current + ch, next); - left.addAll(right); + // Exclude the character + List withoutChar = generateSubsets(current, next); - return left; + withChar.addAll(withoutChar); + return withChar; } } From ef93cc15038aefd29ff3cb4ae2a0fb0df466a767 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Sun, 13 Jul 2025 12:25:26 +0300 Subject: [PATCH 144/146] refactor: `TwoPointers` (#6374) * refactor: TwoPointers * refactor: fix test formatting * refactor: fix checkstyle * refactor: fix checkstyle --- .../com/thealgorithms/others/TwoPointers.java | 33 +++++++++++-------- .../thealgorithms/others/TwoPointersTest.java | 8 +++++ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/thealgorithms/others/TwoPointers.java b/src/main/java/com/thealgorithms/others/TwoPointers.java index c551408c38b9..c87e26269386 100644 --- a/src/main/java/com/thealgorithms/others/TwoPointers.java +++ b/src/main/java/com/thealgorithms/others/TwoPointers.java @@ -7,30 +7,37 @@ *

* Link: https://www.geeksforgeeks.org/two-pointers-technique/ */ -final class TwoPointers { +public final class TwoPointers { + private TwoPointers() { } /** - * Given a sorted array arr (sorted in ascending order), find if there exists - * any pair of elements such that their sum is equal to the key. + * Checks whether there exists a pair of elements in a sorted array whose sum equals the specified key. * - * @param arr the array containing elements (must be sorted in ascending order) - * @param key the number to search - * @return {@code true} if there exists a pair of elements, {@code false} otherwise. + * @param arr a sorted array of integers in ascending order (must not be null) + * @param key the target sum to find + * @return {@code true} if there exists at least one pair whose sum equals {@code key}, {@code false} otherwise + * @throws IllegalArgumentException if {@code arr} is {@code null} */ public static boolean isPairedSum(int[] arr, int key) { - int i = 0; // index of the first element - int j = arr.length - 1; // index of the last element + if (arr == null) { + throw new IllegalArgumentException("Input array must not be null."); + } + + int left = 0; + int right = arr.length - 1; + + while (left < right) { + int sum = arr[left] + arr[right]; - while (i < j) { - int sum = arr[i] + arr[j]; if (sum == key) { return true; - } else if (sum < key) { - i++; + } + if (sum < key) { + left++; } else { - j--; + right--; } } return false; diff --git a/src/test/java/com/thealgorithms/others/TwoPointersTest.java b/src/test/java/com/thealgorithms/others/TwoPointersTest.java index 3a174e0cd19e..6e0d2b22d280 100644 --- a/src/test/java/com/thealgorithms/others/TwoPointersTest.java +++ b/src/test/java/com/thealgorithms/others/TwoPointersTest.java @@ -1,6 +1,8 @@ package com.thealgorithms.others; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; @@ -69,4 +71,10 @@ void testPairExistsAtEdges() { int key = 9; assertTrue(TwoPointers.isPairedSum(arr, key)); } + + @Test + void isPairedSumShouldThrowExceptionWhenArrayIsNull() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> TwoPointers.isPairedSum(null, 10)); + assertEquals("Input array must not be null.", exception.getMessage()); + } } From 933e929b5407fdd69a197cf7821579c14a456a5e Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Mon, 14 Jul 2025 08:47:22 +0300 Subject: [PATCH 145/146] refactor: refactor `Ceil` and improved tests (#6366) * refactor: refactor Ceil and improved tests * checkstyle: remove redundant import * refactor: fix edge cases * refactor: fix checkstyle * refactor: fix checkstyle import order --- .../java/com/thealgorithms/maths/Ceil.java | 27 ++++++++++++----- .../com/thealgorithms/maths/CeilTest.java | 30 ++++++++++++++----- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/Ceil.java b/src/main/java/com/thealgorithms/maths/Ceil.java index aacb9d969950..28804eb1c569 100644 --- a/src/main/java/com/thealgorithms/maths/Ceil.java +++ b/src/main/java/com/thealgorithms/maths/Ceil.java @@ -1,23 +1,34 @@ package com.thealgorithms.maths; +/** + * Utility class to compute the ceiling of a given number. + */ public final class Ceil { + private Ceil() { } /** - * Returns the smallest (closest to negative infinity) + * Returns the smallest double value that is greater than or equal to the input. + * Equivalent to mathematical ⌈x⌉ (ceiling function). * - * @param number the number - * @return the smallest (closest to negative infinity) of given - * {@code number} + * @param number the number to ceil + * @return the smallest double greater than or equal to {@code number} */ public static double ceil(double number) { - if (number - (int) number == 0) { + if (Double.isNaN(number) || Double.isInfinite(number) || number == 0.0 || number < Integer.MIN_VALUE || number > Integer.MAX_VALUE) { return number; - } else if (number - (int) number > 0) { - return (int) (number + 1); + } + + if (number < 0.0 && number > -1.0) { + return -0.0; + } + + long intPart = (long) number; + if (number > 0 && number != intPart) { + return intPart + 1.0; } else { - return (int) number; + return intPart; } } } diff --git a/src/test/java/com/thealgorithms/maths/CeilTest.java b/src/test/java/com/thealgorithms/maths/CeilTest.java index 5596760a8c40..ddd0deed41d3 100644 --- a/src/test/java/com/thealgorithms/maths/CeilTest.java +++ b/src/test/java/com/thealgorithms/maths/CeilTest.java @@ -2,16 +2,30 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; public class CeilTest { - @Test - void testCeil() { - assertEquals(8, Ceil.ceil(7.057)); - assertEquals(8, Ceil.ceil(7.004)); - assertEquals(-13, Ceil.ceil(-13.004)); - assertEquals(1, Ceil.ceil(.98)); - assertEquals(-11, Ceil.ceil(-11.357)); + @ParameterizedTest + @CsvSource({"7.057, 8", "7.004, 8", "-13.004, -13", "0.98, 1", "-11.357, -11"}) + void testCeil(double input, int expected) { + assertEquals(expected, Ceil.ceil(input)); + } + + @ParameterizedTest + @MethodSource("edgeCaseProvider") + void testEdgeCases(TestData data) { + assertEquals(Ceil.ceil(data.input), data.expected); + } + + record TestData(double input, double expected) { + } + + static Stream edgeCaseProvider() { + return Stream.of(new TestData(Double.MAX_VALUE, Double.MAX_VALUE), new TestData(Double.MIN_VALUE, Math.ceil(Double.MIN_VALUE)), new TestData(0.0, Math.ceil(0.0)), new TestData(-0.0, Math.ceil(-0.0)), new TestData(Double.NaN, Math.ceil(Double.NaN)), + new TestData(Double.NEGATIVE_INFINITY, Math.ceil(Double.NEGATIVE_INFINITY)), new TestData(Double.POSITIVE_INFINITY, Math.ceil(Double.POSITIVE_INFINITY))); } } From 25aaa6e06448f9f5100570287e3776e159f20470 Mon Sep 17 00:00:00 2001 From: Oleksandr Klymenko Date: Mon, 14 Jul 2025 08:51:17 +0300 Subject: [PATCH 146/146] refactor: `OnesComplement` Tests Using Parameterized Inputs (#6375) refactor: OnesComplement Tests Using Parameterized Inputs Co-authored-by: Deniz Altunkapan <93663085+DenizAltunkapan@users.noreply.github.com> --- .../bitmanipulation/OnesComplement.java | 25 +++++++++++++------ .../bitmanipulation/OnesComplementTest.java | 17 ++++++++++--- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java b/src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java index c5c068422113..aae3a996e49d 100644 --- a/src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java +++ b/src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java @@ -12,15 +12,24 @@ public final class OnesComplement { private OnesComplement() { } - // Function to get the 1's complement of a binary number + /** + * Returns the 1's complement of a binary string. + * + * @param binary A string representing a binary number (e.g., "1010"). + * @return A string representing the 1's complement. + * @throws IllegalArgumentException if the input is null or contains characters other than '0' or '1'. + */ public static String onesComplement(String binary) { - StringBuilder complement = new StringBuilder(); - // Invert each bit to get the 1's complement - for (int i = 0; i < binary.length(); i++) { - if (binary.charAt(i) == '0') { - complement.append('1'); - } else { - complement.append('0'); + if (binary == null || binary.isEmpty()) { + throw new IllegalArgumentException("Input must be a non-empty binary string."); + } + + StringBuilder complement = new StringBuilder(binary.length()); + for (char bit : binary.toCharArray()) { + switch (bit) { + case '0' -> complement.append('1'); + case '1' -> complement.append('0'); + default -> throw new IllegalArgumentException("Input must contain only '0' and '1'. Found: " + bit); } } return complement.toString(); diff --git a/src/test/java/com/thealgorithms/bitmanipulation/OnesComplementTest.java b/src/test/java/com/thealgorithms/bitmanipulation/OnesComplementTest.java index 6be4eb595f79..0e90ed79f587 100644 --- a/src/test/java/com/thealgorithms/bitmanipulation/OnesComplementTest.java +++ b/src/test/java/com/thealgorithms/bitmanipulation/OnesComplementTest.java @@ -1,8 +1,12 @@ package com.thealgorithms.bitmanipulation; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; /** * Test case for Highest Set Bit @@ -39,9 +43,16 @@ public void testOnesComplementMixedBits() { assertEquals("1001", OnesComplement.onesComplement("0110")); } + @ParameterizedTest + @NullAndEmptySource + public void testOnesComplementNullOrEmptyInputThrowsException(String input) { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> OnesComplement.onesComplement(input)); + assertEquals("Input must be a non-empty binary string.", exception.getMessage()); + } + @Test - public void testOnesComplementEmptyString() { - // Test empty string scenario - assertEquals("", OnesComplement.onesComplement("")); + public void testOnesComplementInvalidCharactersThrowsException() { + Exception exception = assertThrows(IllegalArgumentException.class, () -> OnesComplement.onesComplement("10a1")); + assertTrue(exception.getMessage().startsWith("Input must contain only '0' and '1'")); } }