diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index d9cc4c3c35c5..30b46bbf45b5 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -13,4 +13,5 @@ In order to reduce the number of notifications sent to the maintainers, please:
- [ ] All filenames are in PascalCase.
- [ ] All functions and variable names follow Java naming conventions.
- [ ] All new algorithms have a URL in their comments that points to Wikipedia or other similar explanations.
-- [ ] All new code is formatted with `clang-format -i --style=file path/to/your/file.java`
\ No newline at end of file
+- [ ] All new algorithms include a corresponding test class that validates their functionality.
+- [ ] All new code is formatted with `clang-format -i --style=file path/to/your/file.java`
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 39bde758d68e..c5f200c12836 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -8,7 +8,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- name: Set up JDK
uses: actions/setup-java@v5
with:
diff --git a/.github/workflows/clang-format-lint.yml b/.github/workflows/clang-format-lint.yml
index ca014e115282..dc0c9754ed1b 100644
--- a/.github/workflows/clang-format-lint.yml
+++ b/.github/workflows/clang-format-lint.yml
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: DoozyX/clang-format-lint-action@v0.20
with:
source: './src'
diff --git a/.github/workflows/close-failed-prs.yml b/.github/workflows/close-failed-prs.yml
new file mode 100644
index 000000000000..6deea88f0daf
--- /dev/null
+++ b/.github/workflows/close-failed-prs.yml
@@ -0,0 +1,156 @@
+name: Close stale PRs with failed workflows
+
+on:
+ schedule:
+ - cron: '0 3 * * *' # runs daily at 03:00 UTC
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ issues: write
+ pull-requests: write
+
+jobs:
+ close-stale:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Close stale PRs
+ uses: actions/github-script@v8
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const mainBranches = ['main', 'master'];
+ const cutoffDays = 14;
+ const cutoff = new Date();
+ cutoff.setDate(cutoff.getDate() - cutoffDays);
+
+ console.log(`Checking PRs older than: ${cutoff.toISOString()}`);
+
+ try {
+ const { data: prs } = await github.rest.pulls.list({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ state: 'open',
+ sort: 'updated',
+ direction: 'asc',
+ per_page: 100
+ });
+
+ console.log(`Found ${prs.length} open PRs to check`);
+
+ for (const pr of prs) {
+ try {
+ const updated = new Date(pr.updated_at);
+
+ if (updated > cutoff) {
+ console.log(`⏩ Skipping PR #${pr.number} - updated recently`);
+ continue;
+ }
+
+ console.log(`🔍 Checking PR #${pr.number}: "${pr.title}"`);
+
+ // Get commits
+ const commits = await github.paginate(github.rest.pulls.listCommits, {
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: pr.number,
+ per_page: 100
+ });
+
+ const meaningfulCommits = commits.filter(c => {
+ const msg = c.commit.message.toLowerCase();
+ const date = new Date(c.commit.committer.date);
+ const isMergeFromMain = mainBranches.some(branch =>
+ msg.startsWith(`merge branch '${branch}'`) ||
+ msg.includes(`merge remote-tracking branch '${branch}'`)
+ );
+
+ return !isMergeFromMain && date > cutoff;
+ });
+
+ // Get checks with error handling
+ let hasFailedChecks = false;
+ let allChecksCompleted = false;
+ let hasChecks = false;
+
+ try {
+ const { data: checks } = await github.rest.checks.listForRef({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ ref: pr.head.sha
+ });
+
+ hasChecks = checks.check_runs.length > 0;
+ hasFailedChecks = checks.check_runs.some(c => c.conclusion === 'failure');
+ allChecksCompleted = checks.check_runs.every(c =>
+ c.status === 'completed' || c.status === 'skipped'
+ );
+ } catch (error) {
+ console.log(`⚠️ Could not fetch checks for PR #${pr.number}: ${error.message}`);
+ }
+
+ // Get workflow runs with error handling
+ let hasFailedWorkflows = false;
+ let allWorkflowsCompleted = false;
+ let hasWorkflows = false;
+
+ try {
+ const { data: runs } = await github.rest.actions.listWorkflowRuns({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ head_sha: pr.head.sha,
+ per_page: 50
+ });
+
+ hasWorkflows = runs.workflow_runs.length > 0;
+ hasFailedWorkflows = runs.workflow_runs.some(r => r.conclusion === 'failure');
+ allWorkflowsCompleted = runs.workflow_runs.every(r =>
+ ['completed', 'skipped', 'cancelled'].includes(r.status)
+ );
+
+ console.log(`PR #${pr.number}: ${runs.workflow_runs.length} workflow runs found`);
+
+ } catch (error) {
+ console.log(`⚠️ Could not fetch workflow runs for PR #${pr.number}: ${error.message}`);
+ }
+
+ console.log(`PR #${pr.number}: ${meaningfulCommits.length} meaningful commits`);
+ console.log(`Checks - has: ${hasChecks}, failed: ${hasFailedChecks}, completed: ${allChecksCompleted}`);
+ console.log(`Workflows - has: ${hasWorkflows}, failed: ${hasFailedWorkflows}, completed: ${allWorkflowsCompleted}`);
+
+ // Combine conditions - only consider if we actually have checks/workflows
+ const hasAnyFailure = (hasChecks && hasFailedChecks) || (hasWorkflows && hasFailedWorkflows);
+ const allCompleted = (!hasChecks || allChecksCompleted) && (!hasWorkflows || allWorkflowsCompleted);
+
+ if (meaningfulCommits.length === 0 && hasAnyFailure && allCompleted) {
+ console.log(`✅ Closing PR #${pr.number} (${pr.title})`);
+
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: pr.number,
+ body: `This pull request has been automatically closed because its workflows or checks failed and it has been inactive for more than ${cutoffDays} days. Please fix the workflows and reopen if you'd like to continue. Merging from main/master alone does not count as activity.`
+ });
+
+ await github.rest.pulls.update({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: pr.number,
+ state: 'closed'
+ });
+
+ console.log(`✅ Successfully closed PR #${pr.number}`);
+ } else {
+ console.log(`⏩ Not closing PR #${pr.number} - conditions not met`);
+ }
+
+ } catch (prError) {
+ console.error(`❌ Error processing PR #${pr.number}: ${prError.message}`);
+ continue;
+ }
+ }
+
+ } catch (error) {
+ console.error(`❌ Fatal error: ${error.message}`);
+ throw error;
+ }
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index ef4953afc954..152d0d766fd2 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -21,7 +21,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
- name: Set up JDK
uses: actions/setup-java@v5
@@ -30,7 +30,7 @@ jobs:
distribution: 'temurin'
- name: Initialize CodeQL
- uses: github/codeql-action/init@v3
+ uses: github/codeql-action/init@v4
with:
languages: 'java-kotlin'
@@ -38,7 +38,7 @@ jobs:
run: mvn --batch-mode --update-snapshots verify
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v3
+ uses: github/codeql-action/analyze@v4
with:
category: "/language:java-kotlin"
@@ -52,15 +52,15 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
- name: Initialize CodeQL
- uses: github/codeql-action/init@v3
+ uses: github/codeql-action/init@v4
with:
languages: 'actions'
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v3
+ uses: github/codeql-action/analyze@v4
with:
category: "/language:actions"
...
diff --git a/.github/workflows/infer.yml b/.github/workflows/infer.yml
index 3df7c4b1fc9e..9d4dcf63000b 100644
--- a/.github/workflows/infer.yml
+++ b/.github/workflows/infer.yml
@@ -15,7 +15,7 @@ jobs:
run_infer:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- name: Set up JDK
uses: actions/setup-java@v5
@@ -33,7 +33,7 @@ jobs:
- name: Cache infer build
id: cache-infer
- uses: actions/cache@v4
+ uses: actions/cache@v5
with:
path: infer
key: ${{ runner.os }}-infer-${{ env.year_week }}
@@ -44,7 +44,7 @@ jobs:
cd ..
git clone https://github.com/facebook/infer.git
cd infer
- git checkout 01aaa268f9d38723ba69c139e10f9e2a04b40b1c
+ git checkout 02c2c43b71e4c5110c0be841e66153942fda06c9
./build-infer.sh java
cp -r infer ../Java
diff --git a/.github/workflows/project_structure.yml b/.github/workflows/project_structure.yml
index f9fb82a2781c..5aadc6353791 100644
--- a/.github/workflows/project_structure.yml
+++ b/.github/workflows/project_structure.yml
@@ -15,7 +15,7 @@ jobs:
check_structure:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.13'
diff --git a/.github/workflows/update-directorymd.yml b/.github/workflows/update-directorymd.yml
index 6692a884a867..1cfee6e36e4e 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:
@@ -14,7 +14,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
- name: Run Directory Tree Generator
uses: DenizAltunkapan/directory-tree-generator@v2
@@ -31,7 +33,7 @@ jobs:
git diff --cached --quiet || git commit -m "Update DIRECTORY.md"
- name: Create Pull Request
- uses: peter-evans/create-pull-request@v7
+ uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.REPO_SCOPED_TOKEN }}
branch: update-directory
diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile
index ef76c6fc68a6..a8951da7de26 100644
--- a/.gitpod.dockerfile
+++ b/.gitpod.dockerfile
@@ -1,4 +1,4 @@
-FROM gitpod/workspace-java-21:2025-08-25-18-17-39
+FROM gitpod/workspace-java-21:2025-11-14-10-05-32
ENV LLVM_SCRIPT="tmp_llvm.sh"
diff --git a/.inferconfig b/.inferconfig
index 6af4f9e2e818..239172177b38 100644
--- a/.inferconfig
+++ b/.inferconfig
@@ -1,6 +1,8 @@
{
"report-block-list-path-regex": [
"src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java",
+ "src/main/java/com/thealgorithms/compression/ArithmeticCoding.java",
+ "src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java",
"src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java",
"src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java",
"src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java",
@@ -8,15 +10,18 @@
"src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java",
"src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java",
"src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java",
+ "src/main/java/com/thealgorithms/dynamicprogramming/DamerauLevenshteinDistance.java",
"src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java",
"src/main/java/com/thealgorithms/maths/SimpsonIntegration.java",
"src/main/java/com/thealgorithms/others/Dijkstra.java",
"src/main/java/com/thealgorithms/sorts/TopologicalSort.java",
"src/main/java/com/thealgorithms/strings/AhoCorasick.java",
+ "src/test/java/com/thealgorithms/compression/ShannonFanoTest.java",
"src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java",
"src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java",
"src/test/java/com/thealgorithms/datastructures/trees/KDTreeTest.java",
"src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java",
+ "src/test/java/com/thealgorithms/others/HuffmanTest.java",
"src/test/java/com/thealgorithms/searches/QuickSelectTest.java",
"src/test/java/com/thealgorithms/stacks/PostfixToInfixTest.java",
"src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java"
diff --git a/DIRECTORY.md b/DIRECTORY.md
index 8ae7aea61922..deaf59636fa4 100644
--- a/DIRECTORY.md
+++ b/DIRECTORY.md
@@ -13,6 +13,7 @@
- 📄 [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)
+ - 📄 [CombinationSum](src/main/java/com/thealgorithms/backtracking/CombinationSum.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)
@@ -23,14 +24,19 @@
- 📄 [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)
+ - 📄 [SudokuSolver](src/main/java/com/thealgorithms/backtracking/SudokuSolver.java)
+ - 📄 [UniquePermutation](src/main/java/com/thealgorithms/backtracking/UniquePermutation.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)
+ - 📄 [BitRotate](src/main/java/com/thealgorithms/bitmanipulation/BitRotate.java)
- 📄 [BitSwap](src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java)
+ - 📄 [BitwiseGCD](src/main/java/com/thealgorithms/bitmanipulation/BitwiseGCD.java)
- 📄 [BooleanAlgebraGates](src/main/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGates.java)
- 📄 [ClearLeftmostSetBit](src/main/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBit.java)
+ - 📄 [CountBitsFlip](src/main/java/com/thealgorithms/bitmanipulation/CountBitsFlip.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)
@@ -74,6 +80,8 @@
- 📄 [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)
+ - 📄 [OneTimePadCipher](src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java)
+ - 📄 [PermutationCipher](src/main/java/com/thealgorithms/ciphers/PermutationCipher.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)
@@ -89,14 +97,25 @@
- 📄 [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)
+ - 📁 **compression**
+ - 📄 [ArithmeticCoding](src/main/java/com/thealgorithms/compression/ArithmeticCoding.java)
+ - 📄 [BurrowsWheelerTransform](src/main/java/com/thealgorithms/compression/BurrowsWheelerTransform.java)
+ - 📄 [LZ77](src/main/java/com/thealgorithms/compression/LZ77.java)
+ - 📄 [LZ78](src/main/java/com/thealgorithms/compression/LZ78.java)
+ - 📄 [LZW](src/main/java/com/thealgorithms/compression/LZW.java)
+ - 📄 [MoveToFront](src/main/java/com/thealgorithms/compression/MoveToFront.java)
+ - 📄 [RunLengthEncoding](src/main/java/com/thealgorithms/compression/RunLengthEncoding.java)
+ - 📄 [ShannonFano](src/main/java/com/thealgorithms/compression/ShannonFano.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)
+ - 📄 [Base64](src/main/java/com/thealgorithms/conversions/Base64.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)
+ - 📄 [CoordinateConverter](src/main/java/com/thealgorithms/conversions/CoordinateConverter.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)
@@ -117,6 +136,8 @@
- 📄 [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)
+ - 📄 [TemperatureConverter](src/main/java/com/thealgorithms/conversions/TemperatureConverter.java)
+ - 📄 [TimeConverter](src/main/java/com/thealgorithms/conversions/TimeConverter.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)
@@ -156,6 +177,7 @@
- 📄 [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)
+ - 📄 [DialsAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/DialsAlgorithm.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)
@@ -170,6 +192,7 @@
- 📄 [MatrixGraphs](src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java)
- 📄 [PrimMST](src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java)
- 📄 [TarjansAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java)
+ - 📄 [TwoSat](src/main/java/com/thealgorithms/datastructures/graphs/TwoSat.java)
- 📄 [UndirectedAdjacencyListGraph](src/main/java/com/thealgorithms/datastructures/graphs/UndirectedAdjacencyListGraph.java)
- 📄 [WelshPowell](src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java)
- 📁 **hashmap**
@@ -178,6 +201,7 @@
- 📄 [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)
+ - 📄 [ImmutableHashMap](src/main/java/com/thealgorithms/datastructures/hashmap/hashing/ImmutableHashMap.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)
@@ -189,6 +213,7 @@
- 📄 [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)
+ - 📄 [IndexedPriorityQueue](src/main/java/com/thealgorithms/datastructures/heaps/IndexedPriorityQueue.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)
@@ -198,10 +223,12 @@
- 📄 [MinPriorityQueue](src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java)
- 📁 **lists**
- 📄 [CircleLinkedList](src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java)
+ - 📄 [CircularDoublyLinkedList](src/main/java/com/thealgorithms/datastructures/lists/CircularDoublyLinkedList.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)
+ - 📄 [FlattenMultilevelLinkedList](src/main/java/com/thealgorithms/datastructures/lists/FlattenMultilevelLinkedList.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)
@@ -214,6 +241,7 @@
- 📄 [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)
+ - 📄 [TortoiseHareAlgo](src/main/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgo.java)
- 📁 **queues**
- 📄 [CircularQueue](src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java)
- 📄 [Deque](src/main/java/com/thealgorithms/datastructures/queues/Deque.java)
@@ -240,8 +268,10 @@
- 📄 [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)
+ - 📄 [BinaryTreeToString](src/main/java/com/thealgorithms/datastructures/trees/BinaryTreeToString.java)
- 📄 [BoundaryTraversal](src/main/java/com/thealgorithms/datastructures/trees/BoundaryTraversal.java)
- 📄 [CeilInBinarySearchTree](src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java)
+ - 📄 [CentroidDecomposition](src/main/java/com/thealgorithms/datastructures/trees/CentroidDecomposition.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)
@@ -261,6 +291,7 @@
- 📄 [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)
+ - 📄 [ThreadedBinaryTree](src/main/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTree.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)
@@ -298,6 +329,7 @@
- 📄 [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)
+ - 📄 [DamerauLevenshteinDistance](src/main/java/com/thealgorithms/dynamicprogramming/DamerauLevenshteinDistance.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)
@@ -318,9 +350,11 @@
- 📄 [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)
+ - 📄 [MaximumProductSubarray](src/main/java/com/thealgorithms/dynamicprogramming/MaximumProductSubarray.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)
+ - 📄 [NeedlemanWunsch](src/main/java/com/thealgorithms/dynamicprogramming/NeedlemanWunsch.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)
@@ -328,6 +362,7 @@
- 📄 [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)
+ - 📄 [SmithWaterman](src/main/java/com/thealgorithms/dynamicprogramming/SmithWaterman.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)
@@ -339,18 +374,34 @@
- 📄 [WildcardMatching](src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java)
- 📄 [WineProblem](src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java)
- 📁 **geometry**
+ - 📄 [BentleyOttmann](src/main/java/com/thealgorithms/geometry/BentleyOttmann.java)
- 📄 [BresenhamLine](src/main/java/com/thealgorithms/geometry/BresenhamLine.java)
- 📄 [ConvexHull](src/main/java/com/thealgorithms/geometry/ConvexHull.java)
+ - 📄 [DDALine](src/main/java/com/thealgorithms/geometry/DDALine.java)
- 📄 [GrahamScan](src/main/java/com/thealgorithms/geometry/GrahamScan.java)
+ - 📄 [Haversine](src/main/java/com/thealgorithms/geometry/Haversine.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)
+ - 📄 [WusLine](src/main/java/com/thealgorithms/geometry/WusLine.java)
- 📁 **graph**
+ - 📄 [BronKerbosch](src/main/java/com/thealgorithms/graph/BronKerbosch.java)
- 📄 [ConstrainedShortestPath](src/main/java/com/thealgorithms/graph/ConstrainedShortestPath.java)
+ - 📄 [Dinic](src/main/java/com/thealgorithms/graph/Dinic.java)
+ - 📄 [Edmonds](src/main/java/com/thealgorithms/graph/Edmonds.java)
+ - 📄 [EdmondsKarp](src/main/java/com/thealgorithms/graph/EdmondsKarp.java)
+ - 📄 [GomoryHuTree](src/main/java/com/thealgorithms/graph/GomoryHuTree.java)
+ - 📄 [HierholzerAlgorithm](src/main/java/com/thealgorithms/graph/HierholzerAlgorithm.java)
+ - 📄 [HierholzerEulerianPath](src/main/java/com/thealgorithms/graph/HierholzerEulerianPath.java)
- 📄 [HopcroftKarp](src/main/java/com/thealgorithms/graph/HopcroftKarp.java)
+ - 📄 [HungarianAlgorithm](src/main/java/com/thealgorithms/graph/HungarianAlgorithm.java)
- 📄 [PredecessorConstrainedDfs](src/main/java/com/thealgorithms/graph/PredecessorConstrainedDfs.java)
+ - 📄 [PushRelabel](src/main/java/com/thealgorithms/graph/PushRelabel.java)
+ - 📄 [StoerWagner](src/main/java/com/thealgorithms/graph/StoerWagner.java)
- 📄 [StronglyConnectedComponentOptimized](src/main/java/com/thealgorithms/graph/StronglyConnectedComponentOptimized.java)
- 📄 [TravelingSalesman](src/main/java/com/thealgorithms/graph/TravelingSalesman.java)
+ - 📄 [YensKShortestPaths](src/main/java/com/thealgorithms/graph/YensKShortestPaths.java)
+ - 📄 [ZeroOneBfs](src/main/java/com/thealgorithms/graph/ZeroOneBfs.java)
- 📁 **greedyalgorithms**
- 📄 [ActivitySelection](src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java)
- 📄 [BandwidthAllocation](src/main/java/com/thealgorithms/greedyalgorithms/BandwidthAllocation.java)
@@ -380,6 +431,7 @@
- 📄 [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)
+ - 📄 [AbundantNumber](src/main/java/com/thealgorithms/maths/AbundantNumber.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)
@@ -391,6 +443,7 @@
- 📄 [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)
+ - 📄 [ChebyshevIteration](src/main/java/com/thealgorithms/maths/ChebyshevIteration.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)
@@ -403,11 +456,13 @@
- 📄 [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)
+ - 📄 [EulerPseudoprime](src/main/java/com/thealgorithms/maths/EulerPseudoprime.java)
- 📄 [EulersFunction](src/main/java/com/thealgorithms/maths/EulersFunction.java)
+ - 📄 [EvilNumber](src/main/java/com/thealgorithms/maths/EvilNumber.java)
+ - 📄 [ExtendedEuclideanAlgorithm](src/main/java/com/thealgorithms/maths/ExtendedEuclideanAlgorithm.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)
@@ -425,7 +480,9 @@
- 📄 [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)
+ - 📄 [GermainPrimeAndSafePrime](src/main/java/com/thealgorithms/maths/GermainPrimeAndSafePrime.java)
- 📄 [GoldbachConjecture](src/main/java/com/thealgorithms/maths/GoldbachConjecture.java)
+ - 📄 [HappyNumber](src/main/java/com/thealgorithms/maths/HappyNumber.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)
@@ -439,6 +496,7 @@
- 📄 [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)
+ - 📄 [LuckyNumber](src/main/java/com/thealgorithms/maths/LuckyNumber.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)
@@ -446,9 +504,11 @@
- 📄 [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)
+ - 📄 [Neville](src/main/java/com/thealgorithms/maths/Neville.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)
+ - 📄 [NumberPersistence](src/main/java/com/thealgorithms/maths/NumberPersistence.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)
@@ -456,9 +516,11 @@
- 📄 [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)
+ - 📄 [PiApproximation](src/main/java/com/thealgorithms/maths/PiApproximation.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)
+ - 📄 [PowerOfFour](src/main/java/com/thealgorithms/maths/PowerOfFour.java)
- 📄 [PowerOfTwoOrNot](src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java)
- 📄 [PowerUsingRecursion](src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java)
- 📁 **Prime**
@@ -474,8 +536,10 @@
- 📄 [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)
+ - 📄 [SieveOfAtkin](src/main/java/com/thealgorithms/maths/SieveOfAtkin.java)
- 📄 [SieveOfEratosthenes](src/main/java/com/thealgorithms/maths/SieveOfEratosthenes.java)
- 📄 [SimpsonIntegration](src/main/java/com/thealgorithms/maths/SimpsonIntegration.java)
+ - 📄 [SmithNumber](src/main/java/com/thealgorithms/maths/SmithNumber.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)
@@ -485,6 +549,7 @@
- 📄 [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)
+ - 📄 [SumOfSquares](src/main/java/com/thealgorithms/maths/SumOfSquares.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)
@@ -492,8 +557,10 @@
- 📄 [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)
+ - 📄 [ZellersCongruence](src/main/java/com/thealgorithms/maths/ZellersCongruence.java)
- 📁 **matrix**
- 📄 [InverseOfMatrix](src/main/java/com/thealgorithms/matrix/InverseOfMatrix.java)
+ - 📄 [LUDecomposition](src/main/java/com/thealgorithms/matrix/LUDecomposition.java)
- 📄 [MatrixMultiplication](src/main/java/com/thealgorithms/matrix/MatrixMultiplication.java)
- 📄 [MatrixRank](src/main/java/com/thealgorithms/matrix/MatrixRank.java)
- 📄 [MatrixTranspose](src/main/java/com/thealgorithms/matrix/MatrixTranspose.java)
@@ -502,6 +569,7 @@
- 📄 [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)
+ - 📄 [StochasticMatrix](src/main/java/com/thealgorithms/matrix/StochasticMatrix.java)
- 📁 **matrixexponentiation**
- 📄 [Fibonacci](src/main/java/com/thealgorithms/matrix/matrixexponentiation/Fibonacci.java)
- 📁 **utils**
@@ -537,12 +605,11 @@
- 📄 [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)
+ - 📄 [IterativeFloodFill](src/main/java/com/thealgorithms/others/IterativeFloodFill.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)
@@ -551,18 +618,28 @@
- 📄 [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)
+ - 📄 [MosAlgorithm](src/main/java/com/thealgorithms/others/MosAlgorithm.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)
- 📄 [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)
+ - 📁 **physics**
+ - 📄 [CoulombsLaw](src/main/java/com/thealgorithms/physics/CoulombsLaw.java)
+ - 📄 [DampedOscillator](src/main/java/com/thealgorithms/physics/DampedOscillator.java)
+ - 📄 [ElasticCollision2D](src/main/java/com/thealgorithms/physics/ElasticCollision2D.java)
+ - 📄 [Gravitation](src/main/java/com/thealgorithms/physics/Gravitation.java)
+ - 📄 [GroundToGroundProjectileMotion](src/main/java/com/thealgorithms/physics/GroundToGroundProjectileMotion.java)
+ - 📄 [Kinematics](src/main/java/com/thealgorithms/physics/Kinematics.java)
+ - 📄 [ProjectileMotion](src/main/java/com/thealgorithms/physics/ProjectileMotion.java)
+ - 📄 [SimplePendulumRK4](src/main/java/com/thealgorithms/physics/SimplePendulumRK4.java)
+ - 📄 [SnellLaw](src/main/java/com/thealgorithms/physics/SnellLaw.java)
+ - 📄 [ThinLens](src/main/java/com/thealgorithms/physics/ThinLens.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**
@@ -573,8 +650,11 @@
- 📄 [RandomizedQuickSort](src/main/java/com/thealgorithms/randomized/RandomizedQuickSort.java)
- 📄 [ReservoirSampling](src/main/java/com/thealgorithms/randomized/ReservoirSampling.java)
- 📁 **recursion**
+ - 📄 [DiceThrower](src/main/java/com/thealgorithms/recursion/DiceThrower.java)
+ - 📄 [FactorialRecursion](src/main/java/com/thealgorithms/recursion/FactorialRecursion.java)
- 📄 [FibonacciSeries](src/main/java/com/thealgorithms/recursion/FibonacciSeries.java)
- 📄 [GenerateSubsets](src/main/java/com/thealgorithms/recursion/GenerateSubsets.java)
+ - 📄 [SylvesterSequence](src/main/java/com/thealgorithms/recursion/SylvesterSequence.java)
- 📁 **scheduling**
- 📄 [AgingScheduling](src/main/java/com/thealgorithms/scheduling/AgingScheduling.java)
- 📄 [EDFScheduling](src/main/java/com/thealgorithms/scheduling/EDFScheduling.java)
@@ -608,7 +688,7 @@
- 📄 [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)
+ - 📄 [ExponentialSearch](src/main/java/com/thealgorithms/searches/ExponentialSearch.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)
@@ -629,6 +709,7 @@
- 📄 [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)
+ - 📄 [SentinelLinearSearch](src/main/java/com/thealgorithms/searches/SentinelLinearSearch.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)
@@ -640,6 +721,7 @@
- 📄 [MaxSumKSizeSubarray](src/main/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarray.java)
- 📄 [MaximumSlidingWindow](src/main/java/com/thealgorithms/slidingwindow/MaximumSlidingWindow.java)
- 📄 [MinSumKSizeSubarray](src/main/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarray.java)
+ - 📄 [MinimumWindowSubstring](src/main/java/com/thealgorithms/slidingwindow/MinimumWindowSubstring.java)
- 📄 [ShortestCoprimeSegment](src/main/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegment.java)
- 📁 **sorts**
- 📄 [AdaptiveMergeSort](src/main/java/com/thealgorithms/sorts/AdaptiveMergeSort.java)
@@ -715,9 +797,12 @@
- 📄 [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)
+ - 📄 [TrappingRainwater](src/main/java/com/thealgorithms/stacks/TrappingRainwater.java)
+ - 📄 [ValidParentheses](src/main/java/com/thealgorithms/stacks/ValidParentheses.java)
- 📁 **strings**
- 📄 [AhoCorasick](src/main/java/com/thealgorithms/strings/AhoCorasick.java)
- 📄 [Alphabetical](src/main/java/com/thealgorithms/strings/Alphabetical.java)
+ - 📄 [AlternativeStringArrange](src/main/java/com/thealgorithms/strings/AlternativeStringArrange.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)
@@ -725,8 +810,10 @@
- 📄 [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)
+ - 📄 [Isogram](src/main/java/com/thealgorithms/strings/Isogram.java)
- 📄 [Isomorphic](src/main/java/com/thealgorithms/strings/Isomorphic.java)
- 📄 [KMP](src/main/java/com/thealgorithms/strings/KMP.java)
+ - 📄 [LengthOfLastWord](src/main/java/com/thealgorithms/strings/LengthOfLastWord.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)
@@ -749,6 +836,7 @@
- 📄 [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)
+ - 📄 [ZAlgorithm](src/main/java/com/thealgorithms/strings/ZAlgorithm.java)
- 📁 **zigZagPattern**
- 📄 [ZigZagPattern](src/main/java/com/thealgorithms/strings/zigZagPattern/ZigZagPattern.java)
- 📁 **tree**
@@ -763,6 +851,7 @@
- 📁 **backtracking**
- 📄 [AllPathsFromSourceToTargetTest](src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java)
- 📄 [ArrayCombinationTest](src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java)
+ - 📄 [CombinationSumTest](src/test/java/com/thealgorithms/backtracking/CombinationSumTest.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)
@@ -774,14 +863,19 @@
- 📄 [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)
+ - 📄 [SudokuSolverTest](src/test/java/com/thealgorithms/backtracking/SudokuSolverTest.java)
+ - 📄 [UniquePermutationTest](src/test/java/com/thealgorithms/backtracking/UniquePermutationTest.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)
+ - 📄 [BitRotateTest](src/test/java/com/thealgorithms/bitmanipulation/BitRotateTest.java)
- 📄 [BitSwapTest](src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java)
+ - 📄 [BitwiseGCDTest](src/test/java/com/thealgorithms/bitmanipulation/BitwiseGCDTest.java)
- 📄 [BooleanAlgebraGatesTest](src/test/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGatesTest.java)
- 📄 [ClearLeftmostSetBitTest](src/test/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBitTest.java)
+ - 📄 [CountBitsFlipTest](src/test/java/com/thealgorithms/bitmanipulation/CountBitsFlipTest.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)
@@ -824,6 +918,8 @@
- 📄 [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)
+ - 📄 [OneTimePadCipherTest](src/test/java/com/thealgorithms/ciphers/OneTimePadCipherTest.java)
+ - 📄 [PermutationCipherTest](src/test/java/com/thealgorithms/ciphers/PermutationCipherTest.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)
@@ -835,13 +931,24 @@
- 📄 [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)
+ - 📁 **compression**
+ - 📄 [ArithmeticCodingTest](src/test/java/com/thealgorithms/compression/ArithmeticCodingTest.java)
+ - 📄 [BurrowsWheelerTransformTest](src/test/java/com/thealgorithms/compression/BurrowsWheelerTransformTest.java)
+ - 📄 [LZ77Test](src/test/java/com/thealgorithms/compression/LZ77Test.java)
+ - 📄 [LZ78Test](src/test/java/com/thealgorithms/compression/LZ78Test.java)
+ - 📄 [LZWTest](src/test/java/com/thealgorithms/compression/LZWTest.java)
+ - 📄 [MoveToFrontTest](src/test/java/com/thealgorithms/compression/MoveToFrontTest.java)
+ - 📄 [RunLengthEncodingTest](src/test/java/com/thealgorithms/compression/RunLengthEncodingTest.java)
+ - 📄 [ShannonFanoTest](src/test/java/com/thealgorithms/compression/ShannonFanoTest.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)
+ - 📄 [Base64Test](src/test/java/com/thealgorithms/conversions/Base64Test.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)
+ - 📄 [CoordinateConverterTest](src/test/java/com/thealgorithms/conversions/CoordinateConverterTest.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)
@@ -861,6 +968,8 @@
- 📄 [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)
+ - 📄 [TemperatureConverterTest](src/test/java/com/thealgorithms/conversions/TemperatureConverterTest.java)
+ - 📄 [TimeConverterTest](src/test/java/com/thealgorithms/conversions/TimeConverterTest.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)
@@ -893,8 +1002,11 @@
- 📄 [DynamicArrayTest](src/test/java/com/thealgorithms/datastructures/dynamicarray/DynamicArrayTest.java)
- 📁 **graphs**
- 📄 [AStarTest](src/test/java/com/thealgorithms/datastructures/graphs/AStarTest.java)
+ - 📄 [BellmanFordTest](src/test/java/com/thealgorithms/datastructures/graphs/BellmanFordTest.java)
- 📄 [BipartiteGraphDFSTest](src/test/java/com/thealgorithms/datastructures/graphs/BipartiteGraphDFSTest.java)
- 📄 [BoruvkaAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java)
+ - 📄 [ConnectedComponentTest](src/test/java/com/thealgorithms/datastructures/graphs/ConnectedComponentTest.java)
+ - 📄 [DialsAlgorithmTest](src/test/java/com/thealgorithms/datastructures/graphs/DialsAlgorithmTest.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)
@@ -908,6 +1020,7 @@
- 📄 [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)
+ - 📄 [TwoSatTest](src/test/java/com/thealgorithms/datastructures/graphs/TwoSatTest.java)
- 📄 [WelshPowellTest](src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java)
- 📁 **hashmap**
- 📁 **hashing**
@@ -915,6 +1028,7 @@
- 📄 [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)
+ - 📄 [ImmutableHashMapTest](src/test/java/com/thealgorithms/datastructures/hashmap/hashing/ImmutableHashMapTest.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)
@@ -923,6 +1037,7 @@
- 📄 [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)
+ - 📄 [IndexedPriorityQueueTest](src/test/java/com/thealgorithms/datastructures/heaps/IndexedPriorityQueueTest.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)
@@ -932,9 +1047,11 @@
- 📄 [MinPriorityQueueTest](src/test/java/com/thealgorithms/datastructures/heaps/MinPriorityQueueTest.java)
- 📁 **lists**
- 📄 [CircleLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java)
+ - 📄 [CircularDoublyLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/CircularDoublyLinkedListTest.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)
+ - 📄 [FlattenMultilevelLinkedListTest](src/test/java/com/thealgorithms/datastructures/lists/FlattenMultilevelLinkedListTest.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)
@@ -945,6 +1062,7 @@
- 📄 [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)
+ - 📄 [TortoiseHareAlgoTest](src/test/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgoTest.java)
- 📁 **queues**
- 📄 [CircularQueueTest](src/test/java/com/thealgorithms/datastructures/queues/CircularQueueTest.java)
- 📄 [DequeTest](src/test/java/com/thealgorithms/datastructures/queues/DequeTest.java)
@@ -965,11 +1083,14 @@
- 📄 [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)
+ - 📄 [BSTRecursiveGenericTest](src/test/java/com/thealgorithms/datastructures/trees/BSTRecursiveGenericTest.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)
+ - 📄 [BinaryTreeToStringTest](src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeToStringTest.java)
- 📄 [BoundaryTraversalTest](src/test/java/com/thealgorithms/datastructures/trees/BoundaryTraversalTest.java)
- 📄 [CeilInBinarySearchTreeTest](src/test/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTreeTest.java)
+ - 📄 [CentroidDecompositionTest](src/test/java/com/thealgorithms/datastructures/trees/CentroidDecompositionTest.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)
@@ -983,11 +1104,15 @@
- 📄 [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)
+ - 📄 [ThreadedBinaryTreeTest](src/test/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTreeTest.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)
+ - 📁 **devutils**
+ - 📁 **entities**
+ - 📄 [ProcessDetailsTest](src/test/java/com/thealgorithms/devutils/entities/ProcessDetailsTest.java)
- 📁 **divideandconquer**
- 📄 [BinaryExponentiationTest](src/test/java/com/thealgorithms/divideandconquer/BinaryExponentiationTest.java)
- 📄 [ClosestPairTest](src/test/java/com/thealgorithms/divideandconquer/ClosestPairTest.java)
@@ -1008,6 +1133,7 @@
- 📄 [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)
+ - 📄 [DamerauLevenshteinDistanceTest](src/test/java/com/thealgorithms/dynamicprogramming/DamerauLevenshteinDistanceTest.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)
@@ -1026,9 +1152,11 @@
- 📄 [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)
+ - 📄 [MaximumProductSubarrayTest](src/test/java/com/thealgorithms/dynamicprogramming/MaximumProductSubarrayTest.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)
+ - 📄 [NeedlemanWunschTest](src/test/java/com/thealgorithms/dynamicprogramming/NeedlemanWunschTest.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)
@@ -1036,6 +1164,7 @@
- 📄 [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)
+ - 📄 [SmithWatermanTest](src/test/java/com/thealgorithms/dynamicprogramming/SmithWatermanTest.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)
@@ -1047,18 +1176,34 @@
- 📄 [WildcardMatchingTest](src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java)
- 📄 [WineProblemTest](src/test/java/com/thealgorithms/dynamicprogramming/WineProblemTest.java)
- 📁 **geometry**
+ - 📄 [BentleyOttmannTest](src/test/java/com/thealgorithms/geometry/BentleyOttmannTest.java)
- 📄 [BresenhamLineTest](src/test/java/com/thealgorithms/geometry/BresenhamLineTest.java)
- 📄 [ConvexHullTest](src/test/java/com/thealgorithms/geometry/ConvexHullTest.java)
+ - 📄 [DDALineTest](src/test/java/com/thealgorithms/geometry/DDALineTest.java)
- 📄 [GrahamScanTest](src/test/java/com/thealgorithms/geometry/GrahamScanTest.java)
+ - 📄 [HaversineTest](src/test/java/com/thealgorithms/geometry/HaversineTest.java)
- 📄 [MidpointCircleTest](src/test/java/com/thealgorithms/geometry/MidpointCircleTest.java)
- 📄 [MidpointEllipseTest](src/test/java/com/thealgorithms/geometry/MidpointEllipseTest.java)
- 📄 [PointTest](src/test/java/com/thealgorithms/geometry/PointTest.java)
+ - 📄 [WusLineTest](src/test/java/com/thealgorithms/geometry/WusLineTest.java)
- 📁 **graph**
+ - 📄 [BronKerboschTest](src/test/java/com/thealgorithms/graph/BronKerboschTest.java)
- 📄 [ConstrainedShortestPathTest](src/test/java/com/thealgorithms/graph/ConstrainedShortestPathTest.java)
+ - 📄 [DinicTest](src/test/java/com/thealgorithms/graph/DinicTest.java)
+ - 📄 [EdmondsKarpTest](src/test/java/com/thealgorithms/graph/EdmondsKarpTest.java)
+ - 📄 [EdmondsTest](src/test/java/com/thealgorithms/graph/EdmondsTest.java)
+ - 📄 [GomoryHuTreeTest](src/test/java/com/thealgorithms/graph/GomoryHuTreeTest.java)
+ - 📄 [HierholzerAlgorithmTest](src/test/java/com/thealgorithms/graph/HierholzerAlgorithmTest.java)
+ - 📄 [HierholzerEulerianPathTest](src/test/java/com/thealgorithms/graph/HierholzerEulerianPathTest.java)
- 📄 [HopcroftKarpTest](src/test/java/com/thealgorithms/graph/HopcroftKarpTest.java)
+ - 📄 [HungarianAlgorithmTest](src/test/java/com/thealgorithms/graph/HungarianAlgorithmTest.java)
- 📄 [PredecessorConstrainedDfsTest](src/test/java/com/thealgorithms/graph/PredecessorConstrainedDfsTest.java)
+ - 📄 [PushRelabelTest](src/test/java/com/thealgorithms/graph/PushRelabelTest.java)
+ - 📄 [StoerWagnerTest](src/test/java/com/thealgorithms/graph/StoerWagnerTest.java)
- 📄 [StronglyConnectedComponentOptimizedTest](src/test/java/com/thealgorithms/graph/StronglyConnectedComponentOptimizedTest.java)
- 📄 [TravelingSalesmanTest](src/test/java/com/thealgorithms/graph/TravelingSalesmanTest.java)
+ - 📄 [YensKShortestPathsTest](src/test/java/com/thealgorithms/graph/YensKShortestPathsTest.java)
+ - 📄 [ZeroOneBfsTest](src/test/java/com/thealgorithms/graph/ZeroOneBfsTest.java)
- 📁 **greedyalgorithms**
- 📄 [ActivitySelectionTest](src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java)
- 📄 [BandwidthAllocationTest](src/test/java/com/thealgorithms/greedyalgorithms/BandwidthAllocationTest.java)
@@ -1085,6 +1230,7 @@
- 📄 [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)
+ - 📄 [AbundantNumberTest](src/test/java/com/thealgorithms/maths/AbundantNumberTest.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)
@@ -1096,6 +1242,7 @@
- 📄 [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)
+ - 📄 [ChebyshevIterationTest](src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.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)
@@ -1107,9 +1254,11 @@
- 📄 [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)
+ - 📄 [EulerPseudoprimeTest](src/test/java/com/thealgorithms/maths/EulerPseudoprimeTest.java)
- 📄 [EulersFunctionTest](src/test/java/com/thealgorithms/maths/EulersFunctionTest.java)
+ - 📄 [EvilNumberTest](src/test/java/com/thealgorithms/maths/EvilNumberTest.java)
+ - 📄 [ExtendedEuclideanAlgorithmTest](src/test/java/com/thealgorithms/maths/ExtendedEuclideanAlgorithmTest.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)
@@ -1128,26 +1277,34 @@
- 📄 [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)
+ - 📄 [GermainPrimeAndSafePrimeTest](src/test/java/com/thealgorithms/maths/GermainPrimeAndSafePrimeTest.java)
- 📄 [GoldbachConjectureTest](src/test/java/com/thealgorithms/maths/GoldbachConjectureTest.java)
+ - 📄 [HappyNumberTest](src/test/java/com/thealgorithms/maths/HappyNumberTest.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)
+ - 📄 [JugglerSequenceTest](src/test/java/com/thealgorithms/maths/JugglerSequenceTest.java)
- 📄 [KaprekarNumbersTest](src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java)
- 📄 [KaratsubaMultiplicationTest](src/test/java/com/thealgorithms/maths/KaratsubaMultiplicationTest.java)
+ - 📄 [KeithNumberTest](src/test/java/com/thealgorithms/maths/KeithNumberTest.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)
+ - 📄 [LinearDiophantineEquationsSolverTest](src/test/java/com/thealgorithms/maths/LinearDiophantineEquationsSolverTest.java)
- 📄 [LongDivisionTest](src/test/java/com/thealgorithms/maths/LongDivisionTest.java)
- 📄 [LucasSeriesTest](src/test/java/com/thealgorithms/maths/LucasSeriesTest.java)
+ - 📄 [LuckyNumberTest](src/test/java/com/thealgorithms/maths/LuckyNumberTest.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)
+ - 📄 [NevilleTest](src/test/java/com/thealgorithms/maths/NevilleTest.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)
+ - 📄 [NumberPersistenceTest](src/test/java/com/thealgorithms/maths/NumberPersistenceTest.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)
@@ -1155,8 +1312,10 @@
- 📄 [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)
+ - 📄 [PiApproximationTest](src/test/java/com/thealgorithms/maths/PiApproximationTest.java)
- 📄 [PollardRhoTest](src/test/java/com/thealgorithms/maths/PollardRhoTest.java)
- 📄 [PowTest](src/test/java/com/thealgorithms/maths/PowTest.java)
+ - 📄 [PowerOfFourTest](src/test/java/com/thealgorithms/maths/PowerOfFourTest.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)
@@ -1164,7 +1323,9 @@
- 📄 [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)
+ - 📄 [SieveOfAtkinTest](src/test/java/com/thealgorithms/maths/SieveOfAtkinTest.java)
- 📄 [SieveOfEratosthenesTest](src/test/java/com/thealgorithms/maths/SieveOfEratosthenesTest.java)
+ - 📄 [SmithNumberTest](src/test/java/com/thealgorithms/maths/SmithNumberTest.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)
@@ -1175,12 +1336,14 @@
- 📄 [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)
+ - 📄 [SumOfSquaresTest](src/test/java/com/thealgorithms/maths/SumOfSquaresTest.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)
+ - 📄 [ZellersCongruenceTest](src/test/java/com/thealgorithms/maths/ZellersCongruenceTest.java)
- 📁 **prime**
- 📄 [LiouvilleLambdaFunctionTest](src/test/java/com/thealgorithms/maths/prime/LiouvilleLambdaFunctionTest.java)
- 📄 [MillerRabinPrimalityCheckTest](src/test/java/com/thealgorithms/maths/prime/MillerRabinPrimalityCheckTest.java)
@@ -1189,14 +1352,16 @@
- 📄 [PrimeFactorizationTest](src/test/java/com/thealgorithms/maths/prime/PrimeFactorizationTest.java)
- 📁 **matrix**
- 📄 [InverseOfMatrixTest](src/test/java/com/thealgorithms/matrix/InverseOfMatrixTest.java)
+ - 📄 [LUDecompositionTest](src/test/java/com/thealgorithms/matrix/LUDecompositionTest.java)
- 📄 [MatrixMultiplicationTest](src/test/java/com/thealgorithms/matrix/MatrixMultiplicationTest.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)
+ - 📄 [PrintAMatrixInSpiralOrderTest](src/test/java/com/thealgorithms/matrix/PrintAMatrixInSpiralOrderTest.java)
- 📄 [SolveSystemTest](src/test/java/com/thealgorithms/matrix/SolveSystemTest.java)
- - 📄 [TestPrintMatrixInSpiralOrder](src/test/java/com/thealgorithms/matrix/TestPrintMatrixInSpiralOrder.java)
+ - 📄 [StochasticMatrixTest](src/test/java/com/thealgorithms/matrix/StochasticMatrixTest.java)
- 📁 **misc**
- 📄 [ColorContrastRatioTest](src/test/java/com/thealgorithms/misc/ColorContrastRatioTest.java)
- 📄 [MapReduceTest](src/test/java/com/thealgorithms/misc/MapReduceTest.java)
@@ -1220,23 +1385,39 @@
- 📄 [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)
+ - 📄 [HuffmanTest](src/test/java/com/thealgorithms/others/HuffmanTest.java)
+ - 📄 [InsertDeleteInArrayTest](src/test/java/com/thealgorithms/others/InsertDeleteInArrayTest.java)
+ - 📄 [IterativeFloodFillTest](src/test/java/com/thealgorithms/others/IterativeFloodFillTest.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)
- 📄 [MaximumSumOfDistinctSubarraysWithLengthKTest](src/test/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthKTest.java)
+ - 📄 [MiniMaxAlgorithmTest](src/test/java/com/thealgorithms/others/MiniMaxAlgorithmTest.java)
+ - 📄 [MosAlgorithmTest](src/test/java/com/thealgorithms/others/MosAlgorithmTest.java)
- 📄 [NewManShanksPrimeTest](src/test/java/com/thealgorithms/others/NewManShanksPrimeTest.java)
- 📄 [NextFitTest](src/test/java/com/thealgorithms/others/NextFitTest.java)
+ - 📄 [PageRankTest](src/test/java/com/thealgorithms/others/PageRankTest.java)
- 📄 [PasswordGenTest](src/test/java/com/thealgorithms/others/PasswordGenTest.java)
+ - 📄 [PerlinNoiseTest](src/test/java/com/thealgorithms/others/PerlinNoiseTest.java)
- 📄 [QueueUsingTwoStacksTest](src/test/java/com/thealgorithms/others/QueueUsingTwoStacksTest.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)
+ - 📁 **physics**
+ - 📄 [CoulombsLawTest](src/test/java/com/thealgorithms/physics/CoulombsLawTest.java)
+ - 📄 [DampedOscillatorTest](src/test/java/com/thealgorithms/physics/DampedOscillatorTest.java)
+ - 📄 [ElasticCollision2DTest](src/test/java/com/thealgorithms/physics/ElasticCollision2DTest.java)
+ - 📄 [GravitationTest](src/test/java/com/thealgorithms/physics/GravitationTest.java)
+ - 📄 [GroundToGroundProjectileMotionTest](src/test/java/com/thealgorithms/physics/GroundToGroundProjectileMotionTest.java)
+ - 📄 [KinematicsTest](src/test/java/com/thealgorithms/physics/KinematicsTest.java)
+ - 📄 [ProjectileMotionTest](src/test/java/com/thealgorithms/physics/ProjectileMotionTest.java)
+ - 📄 [SimplePendulumRK4Test](src/test/java/com/thealgorithms/physics/SimplePendulumRK4Test.java)
+ - 📄 [SnellLawTest](src/test/java/com/thealgorithms/physics/SnellLawTest.java)
+ - 📄 [ThinLensTest](src/test/java/com/thealgorithms/physics/ThinLensTest.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**
@@ -1247,8 +1428,11 @@
- 📄 [RandomizedQuickSortTest](src/test/java/com/thealgorithms/randomized/RandomizedQuickSortTest.java)
- 📄 [ReservoirSamplingTest](src/test/java/com/thealgorithms/randomized/ReservoirSamplingTest.java)
- 📁 **recursion**
+ - 📄 [DiceThrowerTest](src/test/java/com/thealgorithms/recursion/DiceThrowerTest.java)
+ - 📄 [FactorialRecursionTest](src/test/java/com/thealgorithms/recursion/FactorialRecursionTest.java)
- 📄 [FibonacciSeriesTest](src/test/java/com/thealgorithms/recursion/FibonacciSeriesTest.java)
- 📄 [GenerateSubsetsTest](src/test/java/com/thealgorithms/recursion/GenerateSubsetsTest.java)
+ - 📄 [SylvesterSequenceTest](src/test/java/com/thealgorithms/recursion/SylvesterSequenceTest.java)
- 📁 **scheduling**
- 📄 [AgingSchedulingTest](src/test/java/com/thealgorithms/scheduling/AgingSchedulingTest.java)
- 📄 [EDFSchedulingTest](src/test/java/com/thealgorithms/scheduling/EDFSchedulingTest.java)
@@ -1303,6 +1487,7 @@
- 📄 [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)
+ - 📄 [SentinelLinearSearchTest](src/test/java/com/thealgorithms/searches/SentinelLinearSearchTest.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)
@@ -1315,6 +1500,7 @@
- 📄 [MaxSumKSizeSubarrayTest](src/test/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarrayTest.java)
- 📄 [MaximumSlidingWindowTest](src/test/java/com/thealgorithms/slidingwindow/MaximumSlidingWindowTest.java)
- 📄 [MinSumKSizeSubarrayTest](src/test/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarrayTest.java)
+ - 📄 [MinimumWindowSubstringTest](src/test/java/com/thealgorithms/slidingwindow/MinimumWindowSubstringTest.java)
- 📄 [ShortestCoprimeSegmentTest](src/test/java/com/thealgorithms/slidingwindow/ShortestCoprimeSegmentTest.java)
- 📁 **sorts**
- 📄 [AdaptiveMergeSortTest](src/test/java/com/thealgorithms/sorts/AdaptiveMergeSortTest.java)
@@ -1388,9 +1574,12 @@
- 📄 [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)
+ - 📄 [TrappingRainwaterTest](src/test/java/com/thealgorithms/stacks/TrappingRainwaterTest.java)
+ - 📄 [ValidParenthesesTest](src/test/java/com/thealgorithms/stacks/ValidParenthesesTest.java)
- 📁 **strings**
- 📄 [AhoCorasickTest](src/test/java/com/thealgorithms/strings/AhoCorasickTest.java)
- 📄 [AlphabeticalTest](src/test/java/com/thealgorithms/strings/AlphabeticalTest.java)
+ - 📄 [AlternativeStringArrangeTest](src/test/java/com/thealgorithms/strings/AlternativeStringArrangeTest.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)
@@ -1398,7 +1587,9 @@
- 📄 [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)
+ - 📄 [IsogramTest](src/test/java/com/thealgorithms/strings/IsogramTest.java)
- 📄 [IsomorphicTest](src/test/java/com/thealgorithms/strings/IsomorphicTest.java)
+ - 📄 [LengthOfLastWordTest](src/test/java/com/thealgorithms/strings/LengthOfLastWordTest.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)
@@ -1420,6 +1611,7 @@
- 📄 [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)
+ - 📄 [ZAlgorithmTest](src/test/java/com/thealgorithms/strings/ZAlgorithmTest.java)
- 📁 **zigZagPattern**
- 📄 [ZigZagPatternTest](src/test/java/com/thealgorithms/strings/zigZagPattern/ZigZagPatternTest.java)
- 📁 **tree**
diff --git a/README-ko.md b/README-ko.md
deleted file mode 100644
index 4f8cab92fc42..000000000000
--- a/README-ko.md
+++ /dev/null
@@ -1,191 +0,0 @@
-# 알고리즘 - 자바
-
-## 이 [개발브런치](https://github.com/TheAlgorithms/Java/tree/Development)는 기존 프로젝트를 Java 프로젝트 구조로 재개발하기 위해 작성되었다. 기여도를 위해 개발 지사로 전환할 수 있다. 자세한 내용은 이 문제를 참조하십시오. 컨트리뷰션을 위해 [개발브런치](https://github.com/TheAlgorithms/Java/tree/Development)로 전환할 수 있다. 자세한 내용은 [이 이슈](https://github.com/TheAlgorithms/Java/issues/474)를 참고하십시오.
-
-### 자바로 구현된 모든 알고리즘들 (교육용)
-
-이것들은 단지 시범을 위한 것이다. 표준 자바 라이브러리에는 성능상의 이유로 더 나은 것들이 구현되어있다
-
-## 정렬 알고리즘
-
-### Bubble(버블 정렬)
-
-![alt text][bubble-image]
-
-From [Wikipedia][bubble-wiki]: 버블 소트(sinking sor라고도 불리움)는 리스트를 반복적인 단계로 접근하여 정렬한다. 각각의 짝을 비교하며, 순서가 잘못된 경우 그접한 아이템들을 스왑하는 알고리즘이다. 더 이상 스왑할 것이 없을 때까지 반복하며, 반복이 끝남음 리스트가 정렬되었음을 의미한다.
-
-**속성**
-
-- 최악의 성능 O(n^2)
-- 최고의 성능 O(n)
-- 평균 성능 O(n^2)
-
-###### View the algorithm in [action][bubble-toptal]
-
-### Insertion(삽입 정렬)
-
-![alt text][insertion-image]
-
-From [Wikipedia][insertion-wiki]: 삽입 정렬은 최종 정렬된 배열(또는 리스트)을 한번에 하나씩 구축하는 알고리즘이다. 이것은 큰 리스트에서 더 나은 알고리즘인 퀵 소트, 힙 소트, 또는 머지 소트보다 훨씬 안좋은 효율을 가진다. 그림에서 각 막대는 정렬해야 하는 배열의 요소를 나타낸다. 상단과 두 번째 상단 막대의 첫 번째 교차점에서 발생하는 것은 두 번째 요소가 첫 번째 요소보다 더 높은 우선 순위를 가지기 때문에 막대로 표시되는 이러한 요소를 교환한 것이다. 이 방법을 반복하면 삽입 정렬이 완료된다.
-
-**속성**
-
-- 최악의 성능 O(n^2)
-- 최고의 성능 O(n)
-- 평균 O(n^2)
-
-###### View the algorithm in [action][insertion-toptal]
-
-### Merge(합병 정렬)
-
-![alt text][merge-image]
-
-From [Wikipedia][merge-wiki]: 컴퓨터 과학에서, 합병 정렬은 효율적인, 범용적인, 비교 기반 정렬 알고리즘이다. 대부분의 구현은 안정적인 분류를 이루는데, 이것은 구현이 정렬된 출력에 동일한 요소의 입력 순서를 유지한다는 것을 의미한다. 합병 정렬은 1945년에 John von Neumann이 발명한 분할 정복 알고리즘이다.
-
-**속성**
-
-- 최악의 성능 O(n log n) (일반적)
-- 최고의 성능 O(n log n)
-- 평균 O(n log n)
-
-###### View the algorithm in [action][merge-toptal]
-
-### Quick(퀵 정렬)
-
-![alt text][quick-image]
-
-From [Wikipedia][quick-wiki]: 퀵 정렬sometimes called partition-exchange sort)은 효율적인 정렬 알고리즘으로, 배열의 요소를 순서대로 정렬하는 체계적인 방법 역활을 한다.
-
-**속성**
-
-- 최악의 성능 O(n^2)
-- 최고의 성능 O(n log n) or O(n) with three-way partition
-- 평균 O(n log n)
-
-###### View the algorithm in [action][quick-toptal]
-
-### Selection(선택 정렬)
-
-![alt text][selection-image]
-
-From [Wikipedia][selection-wiki]: 알고리즘 입력 리스트를 두 부분으로 나눈다 : 첫 부분은 아이템들이 이미 왼쪽에서 오른쪽으로 정렬되었다. 그리고 남은 부분의 아이템들은 나머지 항목을 차지하는 리스트이다. 처음에는 정렬된 리스트는 공백이고 나머지가 전부이다. 오르차순(또는 내림차순) 알고리즘은 가장 작은 요소를 정렬되지 않은 리스트에서 찾고 정렬이 안된 가장 왼쪽(정렬된 리스트) 리스트와 바꾼다. 이렇게 오른쪽으로 나아간다.
-
-**속성**
-
-- 최악의 성능 O(n^2)
-- 최고의 성능 O(n^2)
-- 평균 O(n^2)
-
-###### View the algorithm in [action][selection-toptal]
-
-### Shell(쉘 정렬)
-
-![alt text][shell-image]
-
-From [Wikipedia][shell-wiki]: 쉘 정렬은 멀리 떨어져 있는 항목의 교환을 허용하는 삽입 종류의 일반화이다. 그 아이디어는 모든 n번째 요소가 정렬된 목록을 제공한다는 것을 고려하여 어느 곳에서든지 시작하도록 요소의 목록을 배열하는 것이다. 이러한 목록은 h-sorted로 알려져 있다. 마찬가지로, 각각 개별적으로 정렬된 h 인터리브 목록으로 간주할 수 있다.
-
-**속성**
-
-- 최악의 성능 O(nlog2 2n)
-- 최고의 성능 O(n log n)
-- Average case performance depends on gap sequence
-
-###### View the algorithm in [action][shell-toptal]
-
-### 시간 복잡성 그래프
-
-정렬 알고리즘의 복잡성 비교 (버블 정렬, 삽입 정렬, 선택 정렬)
-
-[복잡성 그래프](https://github.com/prateekiiest/Python/blob/master/sorts/sortinggraphs.png)
-
----
-
-## 검색 알고리즘
-
-### Linear (선형 탐색)
-
-![alt text][linear-image]
-
-From [Wikipedia][linear-wiki]: 선형 탐색 또는 순차 탐색은 목록 내에서 목표값을 찾는 방법이다. 일치 항목이 발견되거나 모든 요소가 탐색될 때까지 목록의 각 요소에 대해 목표값을 순차적으로 검사한다.
-선형 검색은 최악의 선형 시간으로 실행되며 최대 n개의 비교에서 이루어진다. 여기서 n은 목록의 길이다.
-
-**속성**
-
-- 최악의 성능 O(n)
-- 최고의 성능 O(1)
-- 평균 O(n)
-- 최악의 경우 공간 복잡성 O(1) iterative
-
-### Binary (이진 탐색)
-
-![alt text][binary-image]
-
-From [Wikipedia][binary-wiki]: 이진 탐색, (also known as half-interval search or logarithmic search), 은 정렬된 배열 내에서 목표값의 위치를 찾는 검색 알고리즘이다. 목표값을 배열의 중간 요소와 비교한다; 만약 목표값이 동일하지 않으면, 목표물의 절반이 제거되고 검색이 성공할 때까지 나머지 절반에서 속된다.
-
-**속성**
-
-- 최악의 성능 O(log n)
-- 최고의 성능 O(1)
-- 평균 O(log n)
-- 최악의 경우 공간 복잡성 O(1)
-
-[bubble-toptal]: https://www.toptal.com/developers/sorting-algorithms/bubble-sort
-[bubble-wiki]: https://en.wikipedia.org/wiki/Bubble_sort
-[bubble-image]: https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Bubblesort-edited-color.svg/220px-Bubblesort-edited-color.svg.png "Bubble Sort"
-[insertion-toptal]: https://www.toptal.com/developers/sorting-algorithms/insertion-sort
-[insertion-wiki]: https://en.wikipedia.org/wiki/Insertion_sort
-[insertion-image]: https://upload.wikimedia.org/wikipedia/commons/7/7e/Insertionsort-edited.png "Insertion Sort"
-[quick-toptal]: https://www.toptal.com/developers/sorting-algorithms/quick-sort
-[quick-wiki]: https://en.wikipedia.org/wiki/Quicksort
-[quick-image]: https://upload.wikimedia.org/wikipedia/commons/6/6a/Sorting_quicksort_anim.gif "Quick Sort"
-[merge-toptal]: https://www.toptal.com/developers/sorting-algorithms/merge-sort
-[merge-wiki]: https://en.wikipedia.org/wiki/Merge_sort
-[merge-image]: https://upload.wikimedia.org/wikipedia/commons/c/cc/Merge-sort-example-300px.gif "Merge Sort"
-[selection-toptal]: https://www.toptal.com/developers/sorting-algorithms/selection-sort
-[selection-wiki]: https://en.wikipedia.org/wiki/Selection_sort
-[selection-image]: https://upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Selection_sort_animation.gif/250px-Selection_sort_animation.gif "Selection Sort Sort"
-[shell-toptal]: https://www.toptal.com/developers/sorting-algorithms/shell-sort
-[shell-wiki]: https://en.wikipedia.org/wiki/Shellsort
-[shell-image]: https://upload.wikimedia.org/wikipedia/commons/d/d8/Sorting_shellsort_anim.gif "Shell Sort"
-[linear-wiki]: https://en.wikipedia.org/wiki/Linear_search
-[linear-image]: http://www.tutorialspoint.com/data_structures_algorithms/images/linear_search.gif
-[binary-wiki]: https://en.wikipedia.org/wiki/Binary_search_algorithm
-[binary-image]: https://upload.wikimedia.org/wikipedia/commons/f/f7/Binary_search_into_array.png
-
----
-
-## 나머지 알고리즘에 대한 링크
-
-| 전환 | 다이나믹프로그래밍(DP) | 암호 | 그 외 것들 |
-| --------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------ |
-| [Any Base to Any Base](Conversions/AnyBaseToAnyBase.java) | [Coin Change](DynamicProgramming/CoinChange.java) | [Caesar](Ciphers/Caesar.java) | [Heap Sort](Sorts/HeapSort.java) |
-| [Any Base to Decimal](Conversions/AnyBaseToDecimal.java) | [Egg Dropping](DynamicProgramming/EggDropping.java) | [Columnar Transposition Cipher](Ciphers/ColumnarTranspositionCipher.java) | [Palindromic Prime Checker](Misc/PalindromePrime.java) |
-| [Binary to Decimal](Conversions/BinaryToDecimal.java) | [Fibonacci](DynamicProgramming/Fibonacci.java) | [RSA](Ciphers/RSA.java) | More soon... |
-| [Binary to HexaDecimal](Conversions/BinaryToHexadecimal.java) | [Kadane Algorithm](DynamicProgramming/KadaneAlgorithm.java) | more coming soon... |
-| [Binary to Octal](Conversions/BinaryToOctal.java) | [Knapsack](DynamicProgramming/Knapsack.java) |
-| [Decimal To Any Base](Conversions/DecimalToAnyBase.java) | [Longest Common Subsequence](DynamicProgramming/LongestCommonSubsequence.java) |
-| [Decimal To Binary](Conversions/DecimalToBinary.java) | [Longest Increasing Subsequence](DynamicProgramming/LongestIncreasingSubsequence.java) |
-| [Decimal To Hexadecimal](Conversions/DecimalToHexaDecimal.java) | [Rod Cutting](DynamicProgramming/RodCutting.java) |
-| and much more... | and more... |
-
-### 자료 구조
-
-| 그래프 | 힙 | 리스트 | 큐 |
-| ------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------- |
-| | [빈 힙 예외처리](DataStructures/Heaps/EmptyHeapException.java) | [원형 연결리스트](DataStructures/Lists/CircleLinkedList.java) | [제너릭 어레이 리스트 큐](DataStructures/Queues/GenericArrayListQueue.java) |
-| | [힙](DataStructures/Heaps/Heap.java) | [이중 연결리스트](DataStructures/Lists/DoublyLinkedList.java) | [큐](DataStructures/Queues/Queues.java) |
-| [그래프](DataStructures/Graphs/Graphs.java) | [힙 요소](DataStructures/Heaps/HeapElement.java) | [단순 연결리스트](DataStructures/Lists/SinglyLinkedList.java) |
-| [크루스칼 알고리즘](DataStructures/Graphs/Kruskal.java) | [최대힙](DataStructures/Heaps/MaxHeap.java) |
-| [행렬 그래프](DataStructures/Graphs/MatrixGraphs.java) | [최소힙](DataStructures/Heaps/MinHeap.java) |
-| [프림 최소신장트리](DataStructures/Graphs/PrimMST.java) |
-
-| 스택 | 트리 |
-| --------------------------------------------------------------- | ------------------------------------------------- |
-| [노드 스택](DataStructures/Stacks/NodeStack.java) | [AVL 트리](DataStructures/Trees/AVLTree.java) |
-| [연결리스트 스택](DataStructures/Stacks/StackOfLinkedList.java) | [이진 트리](DataStructures/Trees/BinaryTree.java) |
-| [스택](DataStructures/Stacks) | And much more... |
-
-- [Bags](DataStructures/Bags/Bag.java)
-- [Buffer](DataStructures/Buffers/CircularBuffer.java)
-- [HashMap](DataStructures/HashMap/Hashing/HashMap.java)
--
diff --git a/pmd-exclude.properties b/pmd-exclude.properties
index 4c0ed625d884..a3c95b12fa4b 100644
--- a/pmd-exclude.properties
+++ b/pmd-exclude.properties
@@ -88,12 +88,14 @@ 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.MosAlgorithm=UselessMainMethod
com.thealgorithms.others.PageRank=UselessMainMethod,UselessParentheses
com.thealgorithms.others.PerlinNoise=UselessMainMethod,UselessParentheses
com.thealgorithms.others.QueueUsingTwoStacks=UselessParentheses
com.thealgorithms.others.Trieac=UselessMainMethod,UselessParentheses
com.thealgorithms.others.Verhoeff=UnnecessaryFullyQualifiedName,UselessMainMethod
com.thealgorithms.puzzlesandgames.Sudoku=UselessMainMethod
+com.thealgorithms.recursion.DiceThrower=UselessMainMethod
com.thealgorithms.searches.HowManyTimesRotated=UselessMainMethod
com.thealgorithms.searches.InterpolationSearch=UselessParentheses
com.thealgorithms.searches.KMPSearch=UselessParentheses
diff --git a/pom.xml b/pom.xml
index cb00c0f8d32e..65a8fc229647 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@
This algorithm performs a Depth First Search (DFS) traversal while keeping track
+ * of visited vertices to avoid cycles. Whenever the destination vertex is reached,
+ * the current path is stored as one valid path. Key Characteristics: Time Complexity: Space Complexity: This implementation is intended for educational purposes. This class provides methods for both left and right circular rotations,
+ * supporting only 32-bit integer operations with proper shift normalization
+ * and error handling. This class provides a fast binary (Stein's) GCD implementation for {@code long}
+ * inputs and a BigInteger-backed API for full 2's-complement range support (including
+ * {@code Long.MIN_VALUE}). The {@code long} implementation is efficient and avoids
+ * division/modulo operations. For edge-cases that overflow signed-64-bit ranges
+ * (e.g., gcd(Long.MIN_VALUE, 0) = 2^63), use the BigInteger API {@code gcdBig}.
+ *
+ * Behaviour:
+ * Handles negative inputs. If either input is {@code Long.MIN_VALUE} the
+ * method delegates to the BigInteger implementation and will throw {@link ArithmeticException}
+ * if the result cannot be represented as a signed {@code long}.
+ *
+ * @param a first value (may be negative)
+ * @param b second value (may be negative)
+ * @return non-negative gcd as a {@code long}
+ * @throws ArithmeticException when the exact gcd does not fit into a signed {@code long}
+ */
+ public static long gcd(long a, long b) {
+ // Trivial cases
+ if (a == 0L) {
+ return absOrThrowIfOverflow(b);
+ }
+ if (b == 0L) {
+ return absOrThrowIfOverflow(a);
+ }
+
+ // If either is Long.MIN_VALUE, absolute value doesn't fit into signed long.
+ if (a == Long.MIN_VALUE || b == Long.MIN_VALUE) {
+ // Delegate to BigInteger and try to return a long if it fits
+ BigInteger g = gcdBig(BigInteger.valueOf(a), BigInteger.valueOf(b));
+ return g.longValueExact();
+ }
+
+ // Work with non-negative long values now (safe because we excluded Long.MIN_VALUE)
+ a = (a < 0) ? -a : a;
+ b = (b < 0) ? -b : b;
+
+ // Count common factors of 2
+ int commonTwos = Long.numberOfTrailingZeros(a | b);
+
+ // Remove all factors of 2 from a
+ a >>= Long.numberOfTrailingZeros(a);
+
+ while (b != 0L) {
+ // Remove all factors of 2 from b
+ b >>= Long.numberOfTrailingZeros(b);
+
+ // Now both a and b are odd. Ensure a <= b
+ if (a > b) {
+ long tmp = a;
+ a = b;
+ b = tmp;
+ }
+
+ // b >= a; subtract a from b (result is even)
+ b = b - a;
+ }
+
+ // Restore common powers of two
+ return a << commonTwos;
+ }
+
+ /**
+ * Helper to return absolute value of x unless x == Long.MIN_VALUE, in which
+ * case we delegate to BigInteger and throw to indicate overflow.
+ */
+ private static long absOrThrowIfOverflow(long x) {
+ if (x == Long.MIN_VALUE) {
+ // |Long.MIN_VALUE| = 2^63 which does not fit into signed long
+ throw new ArithmeticException("Absolute value of Long.MIN_VALUE does not fit into signed long. Use gcdBig() for full-range support.");
+ }
+ return (x < 0) ? -x : x;
+ }
+
+ /**
+ * Computes GCD for an array of {@code long} values. Returns 0 for empty/null arrays.
+ * If any intermediate gcd cannot be represented in signed long (rare), an ArithmeticException
+ * will be thrown.
+ */
+ public static long gcd(long... values) {
+
+ if (values == null || values.length == 0) {
+ return 0L;
+ }
+ long result = values[0];
+ for (int i = 1; i < values.length; i++) {
+ result = gcd(result, values[i]);
+ if (result == 1L) {
+ return 1L; // early exit
+ }
+ }
+ return result;
+ }
+
+ /**
+ * BigInteger-backed gcd that works for the full integer range (and beyond).
+ * This is the recommended method when inputs may be Long.MIN_VALUE or when you
+ * need an exact result even if it is greater than Long.MAX_VALUE.
+ * @param a first value (may be negative)
+ * @param b second value (may be negative)
+ * @return non-negative gcd as a {@link BigInteger}
+ */
+ public static BigInteger gcdBig(BigInteger a, BigInteger b) {
+
+ if (a == null || b == null) {
+ throw new NullPointerException("Arguments must not be null");
+ }
+ return a.abs().gcd(b.abs());
+ }
+
+ /**
+ * Convenience overload that accepts signed-64 inputs and returns BigInteger gcd.
+ */
+ public static BigInteger gcdBig(long a, long b) {
+ return gcdBig(BigInteger.valueOf(a), BigInteger.valueOf(b));
+ }
+
+ /**
+ * int overload for convenience.
+ */
+ public static int gcd(int a, int b) {
+ return (int) gcd((long) a, (long) b);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/CountBitsFlip.java b/src/main/java/com/thealgorithms/bitmanipulation/CountBitsFlip.java
new file mode 100644
index 000000000000..8d2c757e5e0a
--- /dev/null
+++ b/src/main/java/com/thealgorithms/bitmanipulation/CountBitsFlip.java
@@ -0,0 +1,63 @@
+package com.thealgorithms.bitmanipulation;
+
+/**
+ * Implementation to count number of bits to be flipped to convert A to B
+ *
+ * Problem: Given two numbers A and B, count the number of bits needed to be
+ * flipped to convert A to B.
+ *
+ * Example:
+ * A = 10 (01010 in binary)
+ * B = 20 (10100 in binary)
+ * XOR = 30 (11110 in binary) - positions where bits differ
+ * Answer: 4 bits need to be flipped
+ *
+ * Time Complexity: O(log n) - where n is the number of set bits
+ * Space Complexity: O(1)
+ *
+ *@author [Yash Rajput](https://github.com/the-yash-rajput)
+ */
+public final class CountBitsFlip {
+
+ private CountBitsFlip() {
+ throw new AssertionError("No instances.");
+ }
+
+ /**
+ * Counts the number of bits that need to be flipped to convert a to b
+ *
+ * Algorithm:
+ * 1. XOR a and b to get positions where bits differ
+ * 2. Count the number of set bits in the XOR result
+ * 3. Use Brian Kernighan's algorithm: n & (n-1) removes rightmost set bit
+ *
+ * @param a the source number
+ * @param b the target number
+ * @return the number of bits to flip to convert A to B
+ */
+ public static long countBitsFlip(long a, long b) {
+ int count = 0;
+
+ // XOR gives us positions where bits differ
+ long xorResult = a ^ b;
+
+ // Count set bits using Brian Kernighan's algorithm
+ while (xorResult != 0) {
+ xorResult = xorResult & (xorResult - 1); // Remove rightmost set bit
+ count++;
+ }
+
+ return count;
+ }
+
+ /**
+ * Alternative implementation using Long.bitCount().
+ *
+ * @param a the source number
+ * @param b the target number
+ * @return the number of bits to flip to convert a to b
+ */
+ public static long countBitsFlipAlternative(long a, long b) {
+ return Long.bitCount(a ^ b);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java b/src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java
index 242f35fc35f2..7df522ca8f69 100644
--- a/src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java
+++ b/src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java
@@ -1,79 +1,79 @@
package com.thealgorithms.bitmanipulation;
-public class CountSetBits {
+/**
+ * Utility class to count total set bits from 1 to N
+ * A set bit is a bit in binary representation that is 1
+ *
+ * @author navadeep
+ */
+public final class CountSetBits {
+
+ private CountSetBits() {
+ // Utility class, prevent instantiation
+ }
/**
- * The below algorithm is called as Brian Kernighan's algorithm
- * We can use Brian Kernighan’s algorithm to improve the above naive algorithm’s performance.
- The idea is to only consider the set bits of an integer by turning off its rightmost set bit
- (after counting it), so the next iteration of the loop considers the next rightmost bit.
-
- The expression n & (n-1) can be used to turn off the rightmost set bit of a number n. This
- works as the expression n-1 flips all the bits after the rightmost set bit of n, including the
- rightmost set bit itself. Therefore, n & (n-1) results in the last bit flipped of n.
-
- For example, consider number 52, which is 00110100 in binary, and has a total 3 bits set.
-
- 1st iteration of the loop: n = 52
-
- 00110100 & (n)
- 00110011 (n-1)
- ~~~~~~~~
- 00110000
+ * Counts total number of set bits in all numbers from 1 to n
+ * Time Complexity: O(log n)
+ *
+ * @param n the upper limit (inclusive)
+ * @return total count of set bits from 1 to n
+ * @throws IllegalArgumentException if n is negative
+ */
+ public static int countSetBits(int n) {
+ if (n < 0) {
+ throw new IllegalArgumentException("Input must be non-negative");
+ }
+ if (n == 0) {
+ return 0;
+ }
- 2nd iteration of the loop: n = 48
+ // Find the largest power of 2 <= n
+ int x = largestPowerOf2InNumber(n);
- 00110000 & (n)
- 00101111 (n-1)
- ~~~~~~~~
- 00100000
+ // Total bits at position x: x * 2^(x-1)
+ int bitsAtPositionX = x * (1 << (x - 1));
+ // Remaining numbers after 2^x
+ int remainingNumbers = n - (1 << x) + 1;
- 3rd iteration of the loop: n = 32
+ // Recursively count for the rest
+ int rest = countSetBits(n - (1 << x));
- 00100000 & (n)
- 00011111 (n-1)
- ~~~~~~~~
- 00000000 (n = 0)
+ return bitsAtPositionX + remainingNumbers + rest;
+ }
- * @param num takes Long number whose number of set bit is to be found
- * @return the count of set bits in the binary equivalent
- */
- public long countSetBits(long num) {
- long cnt = 0;
- while (num > 0) {
- cnt++;
- num &= (num - 1);
+ /**
+ * Finds the position of the most significant bit in n
+ *
+ * @param n the number
+ * @return position of MSB (0-indexed from right)
+ */
+ private static int largestPowerOf2InNumber(int n) {
+ int position = 0;
+ while ((1 << position) <= n) {
+ position++;
}
- return cnt;
+ return position - 1;
}
/**
- * This approach takes O(1) running time to count the set bits, but requires a pre-processing.
+ * Alternative naive approach - counts set bits by iterating through all numbers
+ * Time Complexity: O(n log n)
*
- * So, we divide our 32-bit input into 8-bit chunks, with four chunks. We have 8 bits in each chunk.
- *
- * Then the range is from 0-255 (0 to 2^7).
- * So, we may need to count set bits from 0 to 255 in individual chunks.
- *
- * @param num takes a long number
- * @return the count of set bits in the binary equivalent
+ * @param n the upper limit (inclusive)
+ * @return total count of set bits from 1 to n
*/
- public int lookupApproach(int num) {
- int[] table = new int[256];
- table[0] = 0;
-
- for (int i = 1; i < 256; i++) {
- table[i] = (i & 1) + table[i >> 1]; // i >> 1 equals to i/2
+ public static int countSetBitsNaive(int n) {
+ if (n < 0) {
+ throw new IllegalArgumentException("Input must be non-negative");
}
- int res = 0;
- for (int i = 0; i < 4; i++) {
- res += table[num & 0xff];
- num >>= 8;
+ int count = 0;
+ for (int i = 1; i <= n; i++) {
+ count += Integer.bitCount(i);
}
-
- return res;
+ return count;
}
}
diff --git a/src/main/java/com/thealgorithms/ciphers/AES.java b/src/main/java/com/thealgorithms/ciphers/AES.java
index 1c283f6b7655..df51eba55310 100644
--- a/src/main/java/com/thealgorithms/ciphers/AES.java
+++ b/src/main/java/com/thealgorithms/ciphers/AES.java
@@ -2738,7 +2738,7 @@ public static BigInteger decrypt(BigInteger cipherText, BigInteger key) {
public static void main(String[] args) {
try (Scanner input = new Scanner(System.in)) {
- System.out.println("Enter (e) letter for encrpyt or (d) letter for decrypt :");
+ System.out.println("Enter (e) letter for encrypt or (d) letter for decrypt :");
char choice = input.nextLine().charAt(0);
String in;
switch (choice) {
diff --git a/src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java b/src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java
new file mode 100644
index 000000000000..7733f5cb46f2
--- /dev/null
+++ b/src/main/java/com/thealgorithms/ciphers/OneTimePadCipher.java
@@ -0,0 +1,89 @@
+package com.thealgorithms.ciphers;
+
+import java.security.SecureRandom;
+import java.util.Objects;
+
+/**
+ * One-Time Pad (OTP) cipher implementation.
+ *
+ * The One-Time Pad is information-theoretically secure if:
+ * This implementation is for educational purposes only and should not be
+ * used in production systems.
+ */
+public final class OneTimePadCipher {
+
+ private static final SecureRandom RANDOM = new SecureRandom();
+
+ private OneTimePadCipher() {
+ // utility class
+ }
+
+ /**
+ * Generates a random key of the given length in bytes.
+ *
+ * @param length the length of the key in bytes, must be non-negative
+ * @return a new random key
+ * @throws IllegalArgumentException if length is negative
+ */
+ public static byte[] generateKey(int length) {
+ if (length < 0) {
+ throw new IllegalArgumentException("length must be non-negative");
+ }
+ byte[] key = new byte[length];
+ RANDOM.nextBytes(key);
+ return key;
+ }
+
+ /**
+ * Encrypts the given plaintext bytes using the provided key.
+ * The key length must be exactly the same as the plaintext length.
+ *
+ * @param plaintext the plaintext bytes, must not be {@code null}
+ * @param key the one-time pad key bytes, must not be {@code null}
+ * @return the ciphertext bytes
+ * @throws IllegalArgumentException if the key length does not match plaintext length
+ * @throws NullPointerException if plaintext or key is {@code null}
+ */
+ public static byte[] encrypt(byte[] plaintext, byte[] key) {
+ validateInputs(plaintext, key);
+ return xor(plaintext, key);
+ }
+
+ /**
+ * Decrypts the given ciphertext bytes using the provided key.
+ * For a One-Time Pad, decryption is identical to encryption:
+ * {@code plaintext = ciphertext XOR key}.
+ *
+ * @param ciphertext the ciphertext bytes, must not be {@code null}
+ * @param key the one-time pad key bytes, must not be {@code null}
+ * @return the decrypted plaintext bytes
+ * @throws IllegalArgumentException if the key length does not match ciphertext length
+ * @throws NullPointerException if ciphertext or key is {@code null}
+ */
+ public static byte[] decrypt(byte[] ciphertext, byte[] key) {
+ validateInputs(ciphertext, key);
+ return xor(ciphertext, key);
+ }
+
+ private static void validateInputs(byte[] input, byte[] key) {
+ Objects.requireNonNull(input, "input must not be null");
+ Objects.requireNonNull(key, "key must not be null");
+ if (input.length != key.length) {
+ throw new IllegalArgumentException("Key length must match input length");
+ }
+ }
+
+ private static byte[] xor(byte[] data, byte[] key) {
+ byte[] result = new byte[data.length];
+ for (int i = 0; i < data.length; i++) {
+ result[i] = (byte) (data[i] ^ key[i]);
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java b/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java
new file mode 100644
index 000000000000..ce443545db1d
--- /dev/null
+++ b/src/main/java/com/thealgorithms/ciphers/PermutationCipher.java
@@ -0,0 +1,194 @@
+package com.thealgorithms.ciphers;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A Java implementation of Permutation Cipher.
+ * It is a type of transposition cipher in which the plaintext is divided into blocks
+ * and the characters within each block are rearranged according to a fixed permutation key.
+ *
+ * For example, with key {3, 1, 2} and plaintext "HELLO", the text is divided into blocks
+ * of 3 characters: "HEL" and "LO" (with padding). The characters are then rearranged
+ * according to the key positions.
+ *
+ * @author GitHub Copilot
+ */
+public class PermutationCipher {
+
+ private static final char PADDING_CHAR = 'X';
+
+ /**
+ * Encrypts the given plaintext using the permutation cipher with the specified key.
+ *
+ * @param plaintext the text to encrypt
+ * @param key the permutation key (array of integers representing positions)
+ * @return the encrypted text
+ * @throws IllegalArgumentException if the key is invalid
+ */
+ public String encrypt(String plaintext, int[] key) {
+ validateKey(key);
+
+ if (plaintext == null || plaintext.isEmpty()) {
+ return plaintext;
+ }
+
+ // Remove spaces and convert to uppercase for consistent processing
+ String cleanText = plaintext.replaceAll("\\s+", "").toUpperCase();
+
+ // Pad the text to make it divisible by key length
+ String paddedText = padText(cleanText, key.length);
+
+ StringBuilder encrypted = new StringBuilder();
+
+ // Process text in blocks of key length
+ for (int i = 0; i < paddedText.length(); i += key.length) {
+ String block = paddedText.substring(i, Math.min(i + key.length, paddedText.length()));
+ encrypted.append(permuteBlock(block, key));
+ }
+
+ return encrypted.toString();
+ }
+
+ /**
+ * Decrypts the given ciphertext using the permutation cipher with the specified key.
+ *
+ * @param ciphertext the text to decrypt
+ * @param key the permutation key (array of integers representing positions)
+ * @return the decrypted text
+ * @throws IllegalArgumentException if the key is invalid
+ */
+ public String decrypt(String ciphertext, int[] key) {
+ validateKey(key);
+
+ if (ciphertext == null || ciphertext.isEmpty()) {
+ return ciphertext;
+ }
+
+ // Create the inverse permutation
+ int[] inverseKey = createInverseKey(key);
+
+ StringBuilder decrypted = new StringBuilder();
+
+ // Process text in blocks of key length
+ for (int i = 0; i < ciphertext.length(); i += key.length) {
+ String block = ciphertext.substring(i, Math.min(i + key.length, ciphertext.length()));
+ decrypted.append(permuteBlock(block, inverseKey));
+ }
+
+ // Remove padding characters from the end
+ return removePadding(decrypted.toString());
+ }
+ /**
+ * Validates that the permutation key is valid.
+ * A valid key must contain all integers from 1 to n exactly once, where n is the key length.
+ *
+ * @param key the permutation key to validate
+ * @throws IllegalArgumentException if the key is invalid
+ */
+ private void validateKey(int[] key) {
+ if (key == null || key.length == 0) {
+ throw new IllegalArgumentException("Key cannot be null or empty");
+ }
+
+ Set
+ * Arithmetic coding is a form of entropy encoding used in lossless data
+ * compression. It encodes an entire message into a single number, a fraction n
+ * where (0.0 <= n < 1.0). Unlike Huffman coding, which assigns a specific
+ * bit sequence to each symbol, arithmetic coding represents the message as a
+ * sub-interval of the [0, 1) interval.
+ *
+ * This implementation uses BigDecimal for precision to handle the shrinking
+ * intervals, making it suitable for educational purposes to demonstrate the
+ * core logic.
+ *
+ * Time Complexity: O(n*m) for compression and decompression where n is the
+ * length of the input and m is the number of unique symbols, due to the need
+ * to calculate symbol probabilities.
+ *
+ * References:
+ *
+ * BWT is a reversible data transformation algorithm that rearranges a string into runs of
+ * similar characters. While not a compression algorithm itself, it significantly improves
+ * the compressibility of data for subsequent algorithms like Move-to-Front encoding and
+ * Run-Length Encoding.
+ * The transform works by:
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * > combinationSum(int[] candidates, int target) {
+ List
> results = new ArrayList<>();
+ if (candidates == null || candidates.length == 0) {
+ return results;
+ }
+
+ // Sort to help with pruning duplicates and early termination
+ Arrays.sort(candidates);
+ backtrack(candidates, target, 0, new ArrayList<>(), results);
+ return results;
+ }
+
+ private static void backtrack(int[] candidates, int remaining, int start, List
> results) {
+ if (remaining == 0) {
+ // Found valid combination; add a copy
+ results.add(new ArrayList<>(combination));
+ return;
+ }
+
+ for (int i = start; i < candidates.length; i++) {
+ int candidate = candidates[i];
+
+ // If candidate is greater than remaining target, further candidates (sorted) will also be too big
+ if (candidate > remaining) {
+ break;
+ }
+
+ // include candidate
+ combination.add(candidate);
+ // Because we can reuse the same element, we pass i (not i + 1)
+ backtrack(candidates, remaining - candidate, i, combination, results);
+ // backtrack: remove last
+ combination.remove(combination.size() - 1);
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/FloodFill.java b/src/main/java/com/thealgorithms/backtracking/FloodFill.java
index c8219ca8ba7e..0f31a9c5a30e 100644
--- a/src/main/java/com/thealgorithms/backtracking/FloodFill.java
+++ b/src/main/java/com/thealgorithms/backtracking/FloodFill.java
@@ -12,8 +12,8 @@ private FloodFill() {
* Get the color at the given coordinates of a 2D image
*
* @param image The image to be filled
- * @param x The x co-ordinate of which color is to be obtained
- * @param y The y co-ordinate of which color is to be obtained
+ * @param x The x coordinate of which color is to be obtained
+ * @param y The y coordinate of which color is to be obtained
*/
public static int getPixel(final int[][] image, final int x, final int y) {
@@ -24,8 +24,8 @@ public static int getPixel(final int[][] image, final int x, final int y) {
* Put the color at the given coordinates of a 2D image
*
* @param image The image to be filled
- * @param x The x co-ordinate at which color is to be filled
- * @param y The y co-ordinate at which color is to be filled
+ * @param x The x coordinate at which color is to be filled
+ * @param y The y coordinate at which color is to be filled
*/
public static void putPixel(final int[][] image, final int x, final int y, final int newColor) {
image[x][y] = newColor;
@@ -35,8 +35,8 @@ public static void putPixel(final int[][] image, final int x, final int y, final
* Fill the 2D image with new color
*
* @param image The image to be filled
- * @param x The x co-ordinate at which color is to be filled
- * @param y The y co-ordinate at which color is to be filled
+ * @param x The x coordinate at which color is to be filled
+ * @param y The y coordinate at which color is to be filled
* @param newColor The new color which to be filled in the image
* @param oldColor The old color which is to be replaced in the image
*/
diff --git a/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java b/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java
new file mode 100644
index 000000000000..543fe2d02b50
--- /dev/null
+++ b/src/main/java/com/thealgorithms/backtracking/SudokuSolver.java
@@ -0,0 +1,157 @@
+package com.thealgorithms.backtracking;
+
+/**
+ * Sudoku Solver using Backtracking Algorithm
+ * Solves a 9x9 Sudoku puzzle by filling empty cells with valid digits (1-9)
+ *
+ * @author Navadeep0007
+ */
+public final class SudokuSolver {
+
+ private static final int GRID_SIZE = 9;
+ private static final int SUBGRID_SIZE = 3;
+ private static final int EMPTY_CELL = 0;
+
+ private SudokuSolver() {
+ // Utility class, prevent instantiation
+ }
+
+ /**
+ * Solves the Sudoku puzzle using backtracking
+ *
+ * @param board 9x9 Sudoku board with 0 representing empty cells
+ * @return true if puzzle is solved, false otherwise
+ */
+ public static boolean solveSudoku(int[][] board) {
+ if (board == null || board.length != GRID_SIZE) {
+ return false;
+ }
+
+ for (int row = 0; row < GRID_SIZE; row++) {
+ if (board[row].length != GRID_SIZE) {
+ return false;
+ }
+ }
+
+ return solve(board);
+ }
+
+ /**
+ * Recursive helper method to solve the Sudoku puzzle
+ *
+ * @param board the Sudoku board
+ * @return true if solution is found, false otherwise
+ */
+ private static boolean solve(int[][] board) {
+ for (int row = 0; row < GRID_SIZE; row++) {
+ for (int col = 0; col < GRID_SIZE; col++) {
+ if (board[row][col] == EMPTY_CELL) {
+ for (int number = 1; number <= GRID_SIZE; number++) {
+ if (isValidPlacement(board, row, col, number)) {
+ board[row][col] = number;
+
+ if (solve(board)) {
+ return true;
+ }
+
+ // Backtrack
+ board[row][col] = EMPTY_CELL;
+ }
+ }
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Checks if placing a number at given position is valid
+ *
+ * @param board the Sudoku board
+ * @param row row index
+ * @param col column index
+ * @param number number to place (1-9)
+ * @return true if placement is valid, false otherwise
+ */
+ private static boolean isValidPlacement(int[][] board, int row, int col, int number) {
+ return !isNumberInRow(board, row, number) && !isNumberInColumn(board, col, number) && !isNumberInSubgrid(board, row, col, number);
+ }
+
+ /**
+ * Checks if number exists in the given row
+ *
+ * @param board the Sudoku board
+ * @param row row index
+ * @param number number to check
+ * @return true if number exists in row, false otherwise
+ */
+ private static boolean isNumberInRow(int[][] board, int row, int number) {
+ for (int col = 0; col < GRID_SIZE; col++) {
+ if (board[row][col] == number) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if number exists in the given column
+ *
+ * @param board the Sudoku board
+ * @param col column index
+ * @param number number to check
+ * @return true if number exists in column, false otherwise
+ */
+ private static boolean isNumberInColumn(int[][] board, int col, int number) {
+ for (int row = 0; row < GRID_SIZE; row++) {
+ if (board[row][col] == number) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if number exists in the 3x3 subgrid
+ *
+ * @param board the Sudoku board
+ * @param row row index
+ * @param col column index
+ * @param number number to check
+ * @return true if number exists in subgrid, false otherwise
+ */
+ private static boolean isNumberInSubgrid(int[][] board, int row, int col, int number) {
+ int subgridRowStart = row - row % SUBGRID_SIZE;
+ int subgridColStart = col - col % SUBGRID_SIZE;
+
+ for (int i = subgridRowStart; i < subgridRowStart + SUBGRID_SIZE; i++) {
+ for (int j = subgridColStart; j < subgridColStart + SUBGRID_SIZE; j++) {
+ if (board[i][j] == number) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Prints the Sudoku board
+ *
+ * @param board the Sudoku board
+ */
+ public static void printBoard(int[][] board) {
+ for (int row = 0; row < GRID_SIZE; row++) {
+ if (row % SUBGRID_SIZE == 0 && row != 0) {
+ System.out.println("-----------");
+ }
+ for (int col = 0; col < GRID_SIZE; col++) {
+ if (col % SUBGRID_SIZE == 0 && col != 0) {
+ System.out.print("|");
+ }
+ System.out.print(board[row][col]);
+ }
+ System.out.println();
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/backtracking/UniquePermutation.java b/src/main/java/com/thealgorithms/backtracking/UniquePermutation.java
new file mode 100644
index 000000000000..4804e247ab03
--- /dev/null
+++ b/src/main/java/com/thealgorithms/backtracking/UniquePermutation.java
@@ -0,0 +1,62 @@
+package com.thealgorithms.backtracking;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Generates all UNIQUE permutations of a string, even when duplicate characters exist.
+ *
+ * Example:
+ * Input: "AAB"
+ * Output: ["AAB", "ABA", "BAA"]
+ *
+ * Time Complexity: O(n! * n)
+ */
+public final class UniquePermutation {
+
+ private UniquePermutation() {
+ // Prevent instantiation
+ throw new UnsupportedOperationException("Utility class");
+ }
+
+ public static List
+ *
+ */
+public final class BitwiseGCD {
+
+ private BitwiseGCD() {
+ }
+
+ /**
+ * Computes GCD of two long values using Stein's algorithm (binary GCD).
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
Important: The input string should end with a unique end-of-string marker + * (typically '$') that: + *
Time Complexity: + *
Example:
+ *
+ * Input: "banana$"
+ * Output: BWTResult("annb$aa", 4)
+ * - "annb$aa" is the transformed string (groups similar characters)
+ * - 4 is the index of the original string in the sorted rotations
+ *
+ *
+ * @see Burrows–Wheeler transform (Wikipedia)
+ */
+public final class BurrowsWheelerTransform {
+
+ private BurrowsWheelerTransform() {
+ }
+
+ /**
+ * A container for the result of the forward BWT.
+ * + * Contains the transformed string and the index of the original string + * in the sorted rotations matrix, both of which are required for the + * inverse transformation. + *
+ */ + public static class BWTResult { + /** The transformed string (last column of the sorted rotation matrix) */ + public final String transformed; + + /** The index of the original string in the sorted rotations matrix */ + public final int originalIndex; + + /** + * Constructs a BWTResult with the transformed string and original index. + * + * @param transformed the transformed string (L-column) + * @param originalIndex the index of the original string in sorted rotations + */ + public BWTResult(String transformed, int originalIndex) { + this.transformed = transformed; + this.originalIndex = originalIndex; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + BWTResult bwtResult = (BWTResult) obj; + return originalIndex == bwtResult.originalIndex && transformed.equals(bwtResult.transformed); + } + + @Override + public int hashCode() { + return 31 * transformed.hashCode() + originalIndex; + } + + @Override + public String toString() { + return "BWTResult[transformed=" + transformed + ", originalIndex=" + originalIndex + "]"; + } + } + + /** + * Performs the forward Burrows-Wheeler Transform on the input string. + *+ * The algorithm generates all cyclic rotations of the input, sorts them + * lexicographically, and returns the last column of this sorted matrix + * along with the position of the original string. + *
+ * + *Note: It is strongly recommended that the input string ends with + * a unique end-of-string marker (e.g., '$') that is lexicographically smaller + * than any other character in the string. This ensures correct inversion.
+ * + * @param text the input string to transform; must not be {@code null} + * @return a {@link BWTResult} object containing the transformed string (L-column) + * and the index of the original string in the sorted rotations matrix; + * returns {@code BWTResult("", -1)} for empty input + * @throws NullPointerException if {@code text} is {@code null} + */ + public static BWTResult transform(String text) { + if (text == null || text.isEmpty()) { + return new BWTResult("", -1); + } + + int n = text.length(); + + // Generate all rotations of the input string + String[] rotations = new String[n]; + for (int i = 0; i < n; i++) { + rotations[i] = text.substring(i) + text.substring(0, i); + } + + // Sort rotations lexicographically + Arrays.sort(rotations); + int originalIndex = Arrays.binarySearch(rotations, text); + StringBuilder lastColumn = new StringBuilder(n); + for (int i = 0; i < n; i++) { + lastColumn.append(rotations[i].charAt(n - 1)); + } + + return new BWTResult(lastColumn.toString(), originalIndex); + } + + /** + * Performs the inverse Burrows-Wheeler Transform using the LF-mapping technique. + *+ * The LF-mapping (Last-First mapping) is an efficient method to reconstruct + * the original string from the BWT output without explicitly reconstructing + * the entire sorted rotations matrix. + *
+ * + *The algorithm works by: + *
+ * LZ77 is a lossless data compression algorithm that works by finding repeated + * occurrences of data in a sliding window. It replaces subsequent occurrences + * with references (offset, length) to the first occurrence within the window. + *
+ *+ * This implementation uses a simple sliding window and lookahead buffer approach. + * Output format is a sequence of tuples (offset, length, next_character). + *
+ *+ * Time Complexity: O(n*W) in this naive implementation, where n is the input length + * and W is the window size, due to the search for the longest match. More advanced + * data structures (like suffix trees) can improve this. + *
+ *+ * References: + *
+ * LZ78 is a dictionary-based lossless data compression algorithm. It processes + * input data sequentially, building a dictionary of phrases encountered so far. + * It outputs pairs (dictionary_index, next_character), representing + * the longest match found in the dictionary plus the character that follows it. + *
+ *+ * This implementation builds the dictionary dynamically during compression. + * The dictionary index 0 represents the empty string (no prefix). + *
+ *+ * Time Complexity: O(n) on average for compression and decompression, assuming + * efficient dictionary lookups (using a HashMap), where n is the + * length of the input string. + *
+ *+ * References: + *
+ * LZW is a universal lossless data compression algorithm created by Abraham + * Lempel, Jacob Ziv, and Terry Welch. It works by building a dictionary of + * strings encountered during compression and replacing occurrences of those + * strings with a shorter code. + *
+ * + *+ * This implementation handles standard ASCII characters and provides methods for + * both compression and decompression. + *
+ * Time Complexity: O(n) for both compression and decompression, where n is the + * length of the input string. + *
+ * + *+ * References: + *
+ * MTF is a data transformation algorithm that encodes each symbol in the input + * as its current position in a dynamically-maintained list, then moves that symbol + * to the front of the list. This transformation is particularly effective when used + * after the Burrows-Wheeler Transform (BWT), as BWT groups similar characters together. + *
+ * + *The transform converts runs of repeated characters into sequences of small integers + * (often zeros), which are highly compressible by subsequent entropy encoding algorithms + * like Run-Length Encoding (RLE) or Huffman coding. This technique is used in the + * bzip2 compression algorithm. + *
+ * + *How it works: + *
Time Complexity: + *
Example:
+ *+ * Input: "annb$aa" + * Alphabet: "$abn" (initial order) + * Output: [1, 3, 0, 3, 3, 3, 0] + * + * Step-by-step: + * - 'a': index 1 in [$,a,b,n] → output 1, list becomes [a,$,b,n] + * - 'n': index 3 in [a,$,b,n] → output 3, list becomes [n,a,$,b] + * - 'n': index 0 in [n,a,$,b] → output 0, list stays [n,a,$,b] + * - 'b': index 3 in [n,a,$,b] → output 3, list becomes [b,n,a,$] + * - etc. + * + * Notice how repeated 'n' characters produce zeros after the first occurrence! + *+ * + * @see Move-to-front transform (Wikipedia) + */ +public final class MoveToFront { + + private MoveToFront() { + } + + /** + * Performs the forward Move-to-Front transform. + *
+ * Converts the input string into a list of integers, where each integer represents + * the position of the corresponding character in a dynamically-maintained alphabet list. + *
+ * + *Note: All characters in the input text must exist in the provided alphabet, + * otherwise an {@link IllegalArgumentException} is thrown. The alphabet should contain + * all unique characters that may appear in the input.
+ * + * @param text the input string to transform; if empty, returns an empty list + * @param initialAlphabet a string containing the initial ordered set of symbols + * (e.g., "$abn" or the full ASCII set); must not be empty + * when {@code text} is non-empty + * @return a list of integers representing the transformed data, where each integer + * is the index of the corresponding input character in the current alphabet state + * @throws IllegalArgumentException if {@code text} is non-empty and {@code initialAlphabet} + * is {@code null} or empty + * @throws IllegalArgumentException if any character in {@code text} is not found in + * {@code initialAlphabet} + */ + public static List+ * Reconstructs the original string from the list of indices produced by the + * forward transform. This requires the exact same initial alphabet that was + * used in the forward transform. + *
+ * + *Important: The {@code initialAlphabet} parameter must be identical + * to the one used in the forward transform, including character order, or the + * output will be incorrect.
+ * + * @param indices The list of integers from the forward transform. + * @param initialAlphabet the exact same initial alphabet string used for the forward transform; + * if {@code null} or empty, returns an empty string + * @return the original, untransformed string + * @throws IllegalArgumentException if any index in {@code indices} is negative or + * exceeds the current alphabet size + */ + public static String inverseTransform(CollectionRun-Length Encoding is a simple form of lossless data compression in which + * runs of data (sequences in which the same data value occurs in many + * consecutive data elements) are stored as a single data value and count, + * rather than as the original run. + * + *
This implementation provides methods for both compressing and decompressing + * a string. For example: + *
Time Complexity: O(n) for both compression and decompression, where n is the + * length of the input string. + * + *
References: + *
Shannon-Fano coding is an entropy encoding technique for lossless data + * compression. It assigns variable-length codes to symbols based on their + * frequencies of occurrence. It is a precursor to Huffman coding and works by + * recursively partitioning a sorted list of symbols into two sub-lists with + * nearly equal total frequencies. + * + *
The algorithm works as follows: + *
Time Complexity: O(n^2) in this implementation due to the partitioning logic, + * or O(n log n) if a more optimized partitioning strategy is used. + * Sorting takes O(n log n), where n is the number of unique symbols. + * + *
References: + *
+ */ +public final class ShannonFano { + + /** + * Private constructor to prevent instantiation of this utility class. + */ + private ShannonFano() { + } + + /** + * A private inner class to represent a symbol and its frequency. + * Implements Comparable to allow sorting based on frequency. + */ + private static class Symbol implements ComparableThis class provides methods to perform the following conversions: + *
The class is final and cannot be instantiated. + */ +public final class CoordinateConverter { + + private CoordinateConverter() { + // Prevent instantiation + } + + /** + * Converts Cartesian coordinates to Polar coordinates. + * + * @param x the x-coordinate in the Cartesian system; must be a finite number + * @param y the y-coordinate in the Cartesian system; must be a finite number + * @return an array where the first element is the radius (r) and the second element is the angle (theta) in degrees + * @throws IllegalArgumentException if x or y is not a finite number + */ + public static double[] cartesianToPolar(double x, double y) { + if (!Double.isFinite(x) || !Double.isFinite(y)) { + throw new IllegalArgumentException("x and y must be finite numbers."); + } + double r = Math.sqrt(x * x + y * y); + double theta = Math.toDegrees(Math.atan2(y, x)); + return new double[] {r, theta}; + } + + /** + * Converts Polar coordinates to Cartesian coordinates. + * + * @param r the radius in the Polar system; must be non-negative + * @param thetaDegrees the angle (theta) in degrees in the Polar system; must be a finite number + * @return an array where the first element is the x-coordinate and the second element is the y-coordinate in the Cartesian system + * @throws IllegalArgumentException if r is negative or thetaDegrees is not a finite number + */ + public static double[] polarToCartesian(double r, double thetaDegrees) { + if (r < 0) { + throw new IllegalArgumentException("Radius (r) must be non-negative."); + } + if (!Double.isFinite(thetaDegrees)) { + throw new IllegalArgumentException("Theta (angle) must be a finite number."); + } + double theta = Math.toRadians(thetaDegrees); + double x = r * Math.cos(theta); + double y = r * Math.sin(theta); + return new double[] {x, y}; + } +} diff --git a/src/main/java/com/thealgorithms/conversions/TemperatureConverter.java b/src/main/java/com/thealgorithms/conversions/TemperatureConverter.java new file mode 100644 index 000000000000..901db17c665d --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/TemperatureConverter.java @@ -0,0 +1,46 @@ +package com.thealgorithms.conversions; + +/** + * A utility class to convert between different temperature units. + * + *
This class supports conversions between the following units: + *
This class is final and cannot be instantiated. + * + * @author krishna-medapati (https://github.com/krishna-medapati) + * @see Wikipedia: Temperature Conversion + */ +public final class TemperatureConverter { + + private TemperatureConverter() { + } + + public static double celsiusToFahrenheit(double celsius) { + return celsius * 9.0 / 5.0 + 32.0; + } + + public static double celsiusToKelvin(double celsius) { + return celsius + 273.15; + } + + public static double fahrenheitToCelsius(double fahrenheit) { + return (fahrenheit - 32.0) * 5.0 / 9.0; + } + + public static double fahrenheitToKelvin(double fahrenheit) { + return (fahrenheit - 32.0) * 5.0 / 9.0 + 273.15; + } + + public static double kelvinToCelsius(double kelvin) { + return kelvin - 273.15; + } + + public static double kelvinToFahrenheit(double kelvin) { + return (kelvin - 273.15) * 9.0 / 5.0 + 32.0; + } +} diff --git a/src/main/java/com/thealgorithms/conversions/TimeConverter.java b/src/main/java/com/thealgorithms/conversions/TimeConverter.java new file mode 100644 index 000000000000..41cae37d7ad1 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/TimeConverter.java @@ -0,0 +1,97 @@ +package com.thealgorithms.conversions; + +import java.util.Locale; +import java.util.Map; + +/** + * A utility class to convert between different units of time. + * + *
This class supports conversions between the following units: + *
The conversion is based on predefined constants in seconds. + * Results are rounded to three decimal places for consistency. + * + *
This class is final and cannot be instantiated.
+ *
+ * @see Wikipedia: Unit of time
+ */
+public final class TimeConverter {
+
+ private TimeConverter() {
+ // Prevent instantiation
+ }
+
+ /**
+ * Supported time units with their equivalent in seconds.
+ */
+ private enum TimeUnit {
+ SECONDS(1.0),
+ MINUTES(60.0),
+ HOURS(3600.0),
+ DAYS(86400.0),
+ WEEKS(604800.0),
+ MONTHS(2629800.0), // 30.44 days
+ YEARS(31557600.0); // 365.25 days
+
+ private final double seconds;
+
+ TimeUnit(double seconds) {
+ this.seconds = seconds;
+ }
+
+ public double toSeconds(double value) {
+ return value * seconds;
+ }
+
+ public double fromSeconds(double secondsValue) {
+ return secondsValue / seconds;
+ }
+ }
+
+ private static final Map
- * Bloom filters are space-efficient data structures that provide a fast way to test whether an
- * element is a member of a set. They may produce false positives, indicating an element is
+ * Bloom filters are space-efficient data structures that provide a fast way to
+ * test whether an
+ * element is a member of a set. They may produce false positives, indicating an
+ * element is
* in the set when it is not, but they will never produce false negatives.
*
- * This method hashes the element using all defined hash functions and sets the corresponding
+ * This method hashes the element using all defined hash functions and sets the
+ * corresponding
* bits in the bit array.
*
- * This method checks the bits at the positions computed by each hash function. If any of these
- * bits are not set, the element is definitely not in the filter. If all bits are set, the element
+ * This method checks the bits at the positions computed by each hash function.
+ * If any of these
+ * bits are not set, the element is definitely not in the filter. If all bits
+ * are set, the element
* might be in the filter.
*
- * Each instance of this class represents a different hash function based on its index.
+ * Each instance of this class represents a different hash function based on its
+ * index.
*
+ * Brief Idea:
+ *
+ * Complexities:
+ *
+ * Usage Example:
+ * Reference
+ * Example: To add (¬x₁ ∨ x₂), call:
+ *
+ * Mapping rule:
+ * This HashMap does not allow modification of existing instances.
+ * Any update operation returns a new ImmutableHashMap.
+ *
+ * @param Key features:
+ * Complexities:
+ * {@code offer, poll, remove(e), changeKey, decreaseKey, increaseKey} are O(log n);
+ * {@code peek, isEmpty, size, contains} are O(1).
+ */
+public class IndexedPriorityQueue We use IdentityHashMap by default to:
+ * IMPORTANT: The mutator must not change {@code equals/hashCode} of {@code e}
+ * if you migrate this implementation to value-based indexing (HashMap).
+ *
+ * @throws IllegalArgumentException if {@code e} is not in the queue
+ */
+ public void changeKey(E e, Consumer Returns nothing; the standard {@code PriorityQueue} returns a displaced
+ * element in a rare case to help its iterator. We don't need that here, so
+ * we keep the API simple.
+ */
+ @SuppressWarnings("unchecked")
+ private void removeAt(int i) {
+ int n = --size; // last index after removal
+ E moved = (E) heap[n];
+ E removed = (E) heap[i];
+ heap[n] = null; // help GC
+ index.remove(removed); // drop mapping for removed element
+
+ if (i == n) {
+ return; // removed last element; done
+ }
+
+ heap[i] = moved;
+ index.put(moved, i);
+
+ // Try sift-up first (cheap if key decreased); if no movement, sift-down.
+ if (!siftUp(i)) {
+ siftDown(i);
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/datastructures/lists/CircularDoublyLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/CircularDoublyLinkedList.java
new file mode 100644
index 000000000000..fbb48854c449
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/lists/CircularDoublyLinkedList.java
@@ -0,0 +1,118 @@
+package com.thealgorithms.datastructures.lists;
+
+/**
+ * This class is a circular doubly linked list implementation. In a circular
+ * doubly linked list,
+ * the last node points back to the first node and the first node points back to
+ * the last node,
+ * creating a circular chain in both directions.
+ *
+ * This implementation includes basic operations such as appending elements to
+ * the end,
+ * removing elements from a specified position, and converting the list to a
+ * string representation.
+ *
+ * @param The {@code slow} pointer advances by one node per iteration while {@code fast} advances by two.
+ * When {@code fast == null} or {@code fast.next == null}, {@code slow} points to the middle node.
+ * For even-length lists, this returns the second middle node. This method does not modify the input list. Reference: https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare Complexity:
- * Additional contibutions made by: PuneetTri(https://github.com/PuneetTri)
+ * Additional contributions made by: PuneetTri(https://github.com/PuneetTri)
*/
class PriorityQueue {
@@ -32,8 +32,8 @@ class PriorityQueue {
PriorityQueue() {
/* If capacity is not defined, default size of 11 would be used
- * capacity=max+1 because we cant access 0th element of PQ, and to
- * accomodate (max)th elements we need capacity to be max+1.
+ * capacity=max+1 because we can't access 0th element of PQ, and to
+ * accommodate (max)th elements we need capacity to be max+1.
* Parent is at position k, child at position (k*2,k*2+1), if we
* use position 0 in our queue, its child would be at:
* (0*2, 0*2+1) -> (0,0). This is why we start at position 1
@@ -127,7 +127,7 @@ public int remove() {
if (isEmpty()) {
throw new RuntimeException("Queue is Empty");
} else {
- int max = queueArray[1]; // By defintion of our max-heap, value at queueArray[1] pos is
+ int max = queueArray[1]; // By definition of our max-heap, value at queueArray[1] pos is
// the greatest
// Swap max and last element
diff --git a/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java b/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java
index e0309122cc12..07fc5c87b6c4 100644
--- a/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java
+++ b/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java
@@ -1,7 +1,7 @@
package com.thealgorithms.datastructures.trees;
/*
-* Avl is algo that balance itself while adding new alues to tree
+* Avl is algo that balance itself while adding new values to tree
* by rotating branches of binary tree and make itself Binary seaarch tree
* there are four cases which has to tackle
* rotating - left right ,left left,right right,right left
diff --git a/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java b/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java
index 5c1334ffa0e8..2c94224ddeb4 100644
--- a/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java
+++ b/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java
@@ -13,6 +13,7 @@
*
+ * The conversion follows a preorder traversal pattern (root → left → right)
+ * and uses parentheses to denote the tree structure.
+ * Empty parentheses "()" are used to explicitly represent missing left children
+ * when a right child exists, ensuring the structure is unambiguous.
+ *
+ * This implementation matches the logic from LeetCode problem 606:
+ * Construct String from Binary Tree.
+ *
*
@@ -29,7 +29,7 @@
* into an array.Since array is sorted do a binary search over the array to get
* an element equal to or greater than current key. Time Complexity: O(n) for
* traversal of tree and O(lg(n)) for binary search in array. Total = O(n) Space
- * Complexity: O(n) for auxillary array to save inorder representation of tree.
+ * Complexity: O(n) for auxiliary array to save inorder representation of tree.
*
*
* Solution 3: Optimal We can do a DFS search on given tree in following
diff --git a/src/main/java/com/thealgorithms/datastructures/trees/CentroidDecomposition.java b/src/main/java/com/thealgorithms/datastructures/trees/CentroidDecomposition.java
new file mode 100644
index 000000000000..0b29dd6f5f5e
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/trees/CentroidDecomposition.java
@@ -0,0 +1,217 @@
+package com.thealgorithms.datastructures.trees;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Centroid Decomposition is a divide-and-conquer technique for trees.
+ * It recursively partitions a tree by finding centroids - nodes whose removal
+ * creates balanced subtrees (each with at most N/2 nodes).
+ *
+ *
+ * Time Complexity: O(N log N) for construction
+ * Space Complexity: O(N)
+ *
+ *
+ * Applications:
+ * - Distance queries on trees
+ * - Path counting problems
+ * - Nearest neighbor searches
+ *
+ * @see Centroid Decomposition
+ * @see Centroid Decomposition Tutorial
+ * @author lens161
+ */
+public final class CentroidDecomposition {
+
+ private CentroidDecomposition() {
+ }
+
+ /**
+ * Represents the centroid tree structure.
+ */
+ public static final class CentroidTree {
+ private final int n;
+ private final List In this implementation, a node's null left/right pointers are used
+ * to point to the in-order predecessor/successor respectively. Two flags
+ * indicate whether left/right pointers are real children or threads.
+ *
+ * @see Wikipedia:
+ * Threaded binary tree
+ */
+public final class ThreadedBinaryTree {
+
+ private Node root;
+
+ private static final class Node {
+ int value;
+ Node left;
+ Node right;
+ boolean leftIsThread;
+ boolean rightIsThread;
+
+ Node(int value) {
+ this.value = value;
+ this.left = null;
+ this.right = null;
+ this.leftIsThread = false;
+ this.rightIsThread = false;
+ }
+ }
+
+ public ThreadedBinaryTree() {
+ this.root = null;
+ }
+
+ /**
+ * Inserts a value into the threaded binary tree. Duplicate values are inserted
+ * to the right subtree (consistent deterministic rule).
+ *
+ * @param value the integer value to insert
+ */
+ public void insert(int value) {
+ Node newNode = new Node(value);
+ if (root == null) {
+ root = newNode;
+ return;
+ }
+
+ Node current = root;
+ Node parent = null;
+
+ while (true) {
+ parent = current;
+ if (value < current.value) {
+ if (!current.leftIsThread && current.left != null) {
+ current = current.left;
+ } else {
+ break;
+ }
+ } else { // value >= current.value
+ if (!current.rightIsThread && current.right != null) {
+ current = current.right;
+ } else {
+ break;
+ }
+ }
+ }
+
+ if (value < parent.value) {
+ // attach newNode as left child
+ newNode.left = parent.left;
+ newNode.leftIsThread = parent.leftIsThread;
+ newNode.right = parent;
+ newNode.rightIsThread = true;
+
+ parent.left = newNode;
+ parent.leftIsThread = false;
+ } else {
+ // attach newNode as right child
+ newNode.right = parent.right;
+ newNode.rightIsThread = parent.rightIsThread;
+ newNode.left = parent;
+ newNode.leftIsThread = true;
+
+ parent.right = newNode;
+ parent.rightIsThread = false;
+ }
+ }
+
+ /**
+ * Returns the in-order traversal of the tree as a list of integers.
+ * Traversal is done without recursion or an explicit stack by following threads.
+ *
+ * @return list containing the in-order sequence of node values
+ */
+ public List Given an array of integers (which may contain positive numbers, negative
+ * numbers, and zeros), this algorithm finds the contiguous subarray that has
+ * the largest product. The algorithm handles negative numbers efficiently by
+ * tracking both maximum and minimum products, since a negative number can turn
+ * a minimum product into a maximum product. This implementation uses a dynamic programming approach that runs in O(n)
+ * time complexity and O(1) space complexity, making it highly efficient for
+ * large arrays. Uses a sweep-line approach with an event queue and status structure to
+ * efficiently detect intersections in 2D plane geometry. An intersection point is reported when two or more segments cross or touch.
+ * For overlapping segments, only actual crossing/touching points are reported,
+ * not all points along the overlap. The input graph is represented as an adjacency list where {@code adjacency.get(u)} returns the
+ * set of vertices adjacent to {@code u}. The algorithm runs in time proportional to the number of
+ * maximal cliques produced and is widely used for clique enumeration problems. Time complexity: O(E * V^2) in the worst case, but typically faster in practice
+ * and near O(E * sqrt(V)) for unit networks. The graph is represented using a capacity matrix where capacity[u][v] is the
+ * capacity of the directed edge u -> v. Capacities must be non-negative.
+ * The algorithm builds level graphs using BFS and finds blocking flows using DFS
+ * with current-edge optimization. This implementation mirrors the API and validation style of
+ * {@link EdmondsKarp#maxFlow(int[][], int, int)} for consistency. An MSA is a directed graph equivalent of a Minimum Spanning Tree. It is a tree rooted
+ * at a specific vertex 'r' that reaches all other vertices, such that the sum of the
+ * weights of its edges is minimized.
+ *
+ * The algorithm works recursively:
+ * Time Complexity: O(E * V) where E is the number of edges and V is the number of vertices.
+ *
+ * References:
+ *
+ * The algorithm runs in O(V * E^2) time and is a specific implementation of the Ford–Fulkerson
+ * method where the augmenting paths are found using breadth-first search (BFS) to ensure the
+ * shortest augmenting paths (in terms of the number of edges) are used.
+ * The graph is represented with a capacity matrix where {@code capacity[u][v]} denotes the
+ * capacity of the edge from {@code u} to {@code v}. Negative capacities are not allowed. API: {@code buildTree(int[][])} returns {@code {parent, weight}} arrays for the tree.
+ *
+ * @see Wikipedia: Gomory–Hu tree
+ */
+
+public final class GomoryHuTree {
+ private GomoryHuTree() {
+ }
+
+ public static int[][] buildTree(int[][] cap) {
+ validateCapacityMatrix(cap);
+ final int n = cap.length;
+ if (n == 1) {
+ return new int[][] {new int[] {-1}, new int[] {0}};
+ }
+
+ int[] parent = new int[n];
+ int[] weight = new int[n];
+ Arrays.fill(parent, 0);
+ parent[0] = -1;
+ weight[0] = 0;
+
+ for (int s = 1; s < n; s++) {
+ int t = parent[s];
+ MaxFlowResult res = edmondsKarpWithMinCut(cap, s, t);
+ int f = res.flow;
+ weight[s] = f;
+
+ for (int v = 0; v < n; v++) {
+ if (v != s && parent[v] == t && res.reachable[v]) {
+ parent[v] = s;
+ }
+ }
+
+ if (t != 0 && res.reachable[parent[t]]) {
+ parent[s] = parent[t];
+ parent[t] = s;
+ weight[s] = weight[t];
+ weight[t] = f;
+ }
+ }
+ return new int[][] {parent, weight};
+ }
+
+ private static void validateCapacityMatrix(int[][] cap) {
+ if (cap == null || cap.length == 0) {
+ throw new IllegalArgumentException("Capacity matrix must not be null or empty");
+ }
+ final int n = cap.length;
+ for (int i = 0; i < n; i++) {
+ if (cap[i] == null || cap[i].length != n) {
+ throw new IllegalArgumentException("Capacity matrix must be square");
+ }
+ for (int j = 0; j < n; j++) {
+ if (cap[i][j] < 0) {
+ throw new IllegalArgumentException("Capacities must be non-negative");
+ }
+ }
+ }
+ }
+
+ private static final class MaxFlowResult {
+ final int flow;
+ final boolean[] reachable;
+ MaxFlowResult(int flow, boolean[] reachable) {
+ this.flow = flow;
+ this.reachable = reachable;
+ }
+ }
+
+ private static MaxFlowResult edmondsKarpWithMinCut(int[][] capacity, int source, int sink) {
+ final int n = capacity.length;
+ int[][] residual = new int[n][n];
+ for (int i = 0; i < n; i++) {
+ residual[i] = Arrays.copyOf(capacity[i], n);
+ }
+
+ int[] parent = new int[n];
+ int maxFlow = 0;
+
+ while (bfs(residual, source, sink, parent)) {
+ int pathFlow = Integer.MAX_VALUE;
+ for (int v = sink; v != source; v = parent[v]) {
+ int u = parent[v];
+ pathFlow = Math.min(pathFlow, residual[u][v]);
+ }
+ for (int v = sink; v != source; v = parent[v]) {
+ int u = parent[v];
+ residual[u][v] -= pathFlow;
+ residual[v][u] += pathFlow;
+ }
+ maxFlow += pathFlow;
+ }
+
+ boolean[] reachable = new boolean[n];
+ markReachable(residual, source, reachable);
+ return new MaxFlowResult(maxFlow, reachable);
+ }
+
+ private static boolean bfs(int[][] residual, int source, int sink, int[] parent) {
+ Arrays.fill(parent, -1);
+ parent[source] = source;
+ Queue
+ * An Eulerian circuit is a trail in a graph that visits every edge exactly once,
+ * starting and ending at the same vertex. This algorithm finds such a circuit if one exists.
+ *
+ * This implementation is designed for an undirected graph. For a valid Eulerian
+ * circuit to exist, the graph must satisfy two conditions:
+ *
+ * The algorithm runs in O(E + V) time, where E is the number of edges and V is the number of vertices.
+ * The graph is represented by a Map where keys are vertices and values are a LinkedList of adjacent vertices.
+ *
+ * An Eulerian Circuit is a path that starts and ends at the same vertex
+ * and visits every edge exactly once.
+ *
+ * An Eulerian Path visits every edge exactly once but may start and end
+ * at different vertices.
+ *
+ * Algorithm Summary:
+ * Time Complexity: O(E + V). Given an n x m cost matrix (n tasks, m workers), finds a minimum-cost
+ * one-to-one assignment. If the matrix is rectangular, the algorithm pads to a
+ * square internally. Costs must be finite non-negative integers.
+ *
+ * Time complexity: O(n^3) with n = max(rows, cols).
+ *
+ * API returns the assignment as an array where {@code assignment[i]} is the
+ * column chosen for row i (or -1 if unassigned when rows != cols), and a total
+ * minimal cost.
+ *
+ * @see Wikipedia: Hungarian algorithm
+ */
+public final class HungarianAlgorithm {
+
+ private HungarianAlgorithm() {
+ }
+
+ /** Result holder for the Hungarian algorithm. */
+ public static final class Result {
+ public final int[] assignment; // assignment[row] = col or -1
+ public final int minCost;
+
+ public Result(int[] assignment, int minCost) {
+ this.assignment = assignment;
+ this.minCost = minCost;
+ }
+ }
+
+ /**
+ * Solves the assignment problem for a non-negative cost matrix.
+ *
+ * @param cost an r x c matrix of non-negative costs
+ * @return Result with row-to-column assignment and minimal total cost
+ * @throws IllegalArgumentException for null/empty or negative costs
+ */
+ public static Result solve(int[][] cost) {
+ validate(cost);
+ int rows = cost.length;
+ int cols = cost[0].length;
+ int n = Math.max(rows, cols);
+
+ // Build square matrix with padding 0 for missing cells
+ int[][] a = new int[n][n];
+ for (int i = 0; i < n; i++) {
+ if (i < rows) {
+ for (int j = 0; j < n; j++) {
+ a[i][j] = (j < cols) ? cost[i][j] : 0;
+ }
+ } else {
+ Arrays.fill(a[i], 0);
+ }
+ }
+
+ // Potentials and matching arrays
+ int[] u = new int[n + 1];
+ int[] v = new int[n + 1];
+ int[] p = new int[n + 1];
+ int[] way = new int[n + 1];
+
+ for (int i = 1; i <= n; i++) {
+ p[0] = i;
+ int j0 = 0;
+ int[] minv = new int[n + 1];
+ boolean[] used = new boolean[n + 1];
+ Arrays.fill(minv, Integer.MAX_VALUE);
+ Arrays.fill(used, false);
+ do {
+ used[j0] = true;
+ int i0 = p[j0];
+ int delta = Integer.MAX_VALUE;
+ int j1 = 0;
+ for (int j = 1; j <= n; j++) {
+ if (!used[j]) {
+ int cur = a[i0 - 1][j - 1] - u[i0] - v[j];
+ if (cur < minv[j]) {
+ minv[j] = cur;
+ way[j] = j0;
+ }
+ if (minv[j] < delta) {
+ delta = minv[j];
+ j1 = j;
+ }
+ }
+ }
+ for (int j = 0; j <= n; j++) {
+ if (used[j]) {
+ u[p[j]] += delta;
+ v[j] -= delta;
+ } else {
+ minv[j] -= delta;
+ }
+ }
+ j0 = j1;
+ } while (p[j0] != 0);
+ do {
+ int j1 = way[j0];
+ p[j0] = p[j1];
+ j0 = j1;
+ } while (j0 != 0);
+ }
+
+ int[] matchColForRow = new int[n];
+ Arrays.fill(matchColForRow, -1);
+ for (int j = 1; j <= n; j++) {
+ if (p[j] != 0) {
+ matchColForRow[p[j] - 1] = j - 1;
+ }
+ }
+
+ // Build assignment for original rows only, ignore padded rows
+ int[] assignment = new int[rows];
+ Arrays.fill(assignment, -1);
+ int total = 0;
+ for (int i = 0; i < rows; i++) {
+ int j = matchColForRow[i];
+ if (j >= 0 && j < cols) {
+ assignment[i] = j;
+ total += cost[i][j];
+ }
+ }
+ return new Result(assignment, total);
+ }
+
+ private static void validate(int[][] cost) {
+ if (cost == null || cost.length == 0) {
+ throw new IllegalArgumentException("Cost matrix must not be null or empty");
+ }
+ int c = cost[0].length;
+ if (c == 0) {
+ throw new IllegalArgumentException("Cost matrix must have at least 1 column");
+ }
+ for (int i = 0; i < cost.length; i++) {
+ if (cost[i] == null || cost[i].length != c) {
+ throw new IllegalArgumentException("Cost matrix must be rectangular with equal row lengths");
+ }
+ for (int j = 0; j < c; j++) {
+ if (cost[i][j] < 0) {
+ throw new IllegalArgumentException("Costs must be non-negative");
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/thealgorithms/graph/PushRelabel.java b/src/main/java/com/thealgorithms/graph/PushRelabel.java
new file mode 100644
index 000000000000..1bfb5ceacce0
--- /dev/null
+++ b/src/main/java/com/thealgorithms/graph/PushRelabel.java
@@ -0,0 +1,162 @@
+package com.thealgorithms.graph;
+
+import java.util.ArrayDeque;
+import java.util.Arrays;
+import java.util.Queue;
+
+/**
+ * Push–Relabel (Relabel-to-Front variant simplified to array scanning) for maximum flow.
+ *
+ * Input graph is a capacity matrix where {@code capacity[u][v]} is the capacity of the edge
+ * {@code u -> v}. Capacities must be non-negative. Vertices are indexed in {@code [0, n)}.
+ *
+ * Time complexity: O(V^3) in the worst case for the array-based variant; typically fast in
+ * practice. This implementation uses a residual network over an adjacency-matrix representation.
+ *
+ * The API mirrors {@link EdmondsKarp#maxFlow(int[][], int, int)} and {@link Dinic#maxFlow(int[][], int, int)}.
+ *
+ * @see Wikipedia: Push–Relabel maximum flow algorithm
+ */
+public final class PushRelabel {
+
+ private PushRelabel() {
+ }
+
+ /**
+ * Computes the maximum flow from {@code source} to {@code sink} using Push–Relabel.
+ *
+ * @param capacity square capacity matrix (n x n); entries must be >= 0
+ * @param source source vertex index in [0, n)
+ * @param sink sink vertex index in [0, n)
+ * @return the maximum flow value
+ * @throws IllegalArgumentException if inputs are invalid
+ */
+ public static int maxFlow(int[][] capacity, int source, int sink) {
+ validate(capacity, source, sink);
+ final int n = capacity.length;
+ if (source == sink) {
+ return 0;
+ }
+
+ int[][] residual = new int[n][n];
+ for (int i = 0; i < n; i++) {
+ residual[i] = Arrays.copyOf(capacity[i], n);
+ }
+
+ int[] height = new int[n];
+ int[] excess = new int[n];
+ int[] nextNeighbor = new int[n];
+
+ // Preflow initialization
+ height[source] = n;
+ for (int v = 0; v < n; v++) {
+ int cap = residual[source][v];
+ if (cap > 0) {
+ residual[source][v] -= cap;
+ residual[v][source] += cap;
+ excess[v] += cap;
+ excess[source] -= cap;
+ }
+ }
+
+ // Active queue contains vertices (except source/sink) with positive excess
+ Queue Input is an adjacency matrix of edge weights. A value of -1 indicates no edge.
+ * All existing edge weights must be non-negative. Zero-weight edges are allowed. References:
+ * - Wikipedia: Yen's algorithm (https://en.wikipedia.org/wiki/Yen%27s_algorithm)
+ * - Dijkstra's algorithm for the base shortest path computation.> graph, int source, int maxEdgeWeight) {
+ int numVertices = graph.size();
+ if (source < 0 || source >= numVertices) {
+ throw new IllegalArgumentException("Source vertex is out of bounds.");
+ }
+
+ // Initialize distances array
+ int[] distances = new int[numVertices];
+ Arrays.fill(distances, Integer.MAX_VALUE);
+ distances[source] = 0;
+
+ // The bucket queue. Size is determined by the max possible path length.
+ int maxPathWeight = maxEdgeWeight * (numVertices > 0 ? numVertices - 1 : 0);
+ List
+ * 1. From each clause (a ∨ b), we can derive implications:
+ * (¬a → b) and (¬b → a)
+ *
+ * 2. We construct an implication graph using these implications.
+ *
+ * 3. For each variable x, its negation ¬x is also represented as a node.
+ * If x and ¬x belong to the same SCC, the expression is unsatisfiable.
+ *
+ * 4. Otherwise, we assign truth values based on the SCC order:
+ * If SCC(x) > SCC(¬x), then x = true; otherwise, x = false.
+ *
+ *
+ *
+ *
+ * where {@code n} is the number of variables and {@code m} is the number of
+ * clauses.
+ *
+ *
+ * TwoSat twoSat = new TwoSat(5); // Initialize with 5 variables: x1, x2, x3, x4, x5
+ *
+ * // Add clauses
+ * twoSat.addClause(1, false, 2, false); // (x1 ∨ x2)
+ * twoSat.addClause(3, true, 2, false); // (¬x3 ∨ x2)
+ * twoSat.addClause(4, false, 5, true); // (x4 ∨ ¬x5)
+ *
+ * twoSat.solve(); // Solve the problem
+ *
+ * if (twoSat.isSolutionExists()) {
+ * boolean[] solution = twoSat.getSolutions();
+ * for (int i = 1; i <= 5; i++) {
+ * System.out.println("x" + i + " = " + solution[i]);
+ * }
+ * }
+ *
+ *
+ * Wikipedia - 2 SAT
+ * @author Shoyeb Ansari
+ *
+ * @see Kosaraju
+ */
+class TwoSat {
+
+ /** Number of variables in the boolean expression. */
+ private final int numberOfVariables;
+
+ /** Implication graph built from the boolean clauses. */
+ private final ArrayList{@code
+ * addClause(1, true, 2, false);
+ * }
+ *
+ * @param a the first variable (1 ≤ a ≤ numberOfVariables)
+ * @param isNegateA {@code true} if variable {@code a} is negated
+ * @param b the second variable (1 ≤ b ≤ numberOfVariables)
+ * @param isNegateB {@code true} if variable {@code b} is negated
+ * @throws IllegalArgumentException if {@code a} or {@code b} are out of range
+ */
+ void addClause(int a, boolean isNegateA, int b, boolean isNegateB) {
+ if (a <= 0 || a > numberOfVariables) {
+ throw new IllegalArgumentException("Variable number must be between 1 and " + numberOfVariables);
+ }
+ if (b <= 0 || b > numberOfVariables) {
+ throw new IllegalArgumentException("Variable number must be between 1 and " + numberOfVariables);
+ }
+
+ a = isNegateA ? negate(a) : a;
+ b = isNegateB ? negate(b) : b;
+ int notA = negate(a);
+ int notB = negate(b);
+
+ // Add implications: (¬a → b) and (¬b → a)
+ graph[notA].add(b);
+ graph[notB].add(a);
+
+ // Build transpose graph
+ graphTranspose[b].add(notA);
+ graphTranspose[a].add(notB);
+ }
+
+ /**
+ * Solves the 2-SAT problem using Kosaraju's algorithm to find SCCs
+ * and determines whether a satisfying assignment exists.
+ */
+ void solve() {
+ isSolved = true;
+ int n = 2 * numberOfVariables + 1;
+
+ boolean[] visited = new boolean[n];
+ int[] component = new int[n];
+ Stack
+ * For a variable i:
+ * negate(i) = i + n
+ * For a negated variable (i + n):
+ * negate(i + n) = i
+ * where n = numberOfVariables
+ *
+ *
+ * @param a the variable index
+ * @return the index representing its negation
+ */
+ private int negate(int a) {
+ return a <= numberOfVariables ? a + numberOfVariables : a - numberOfVariables;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md b/src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md
index 252b06ea59b0..4400a97d8128 100644
--- a/src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md
+++ b/src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md
@@ -2,6 +2,8 @@
A hash map organizes data so you can quickly look up values for a given key.
+> Note: The term “hash map” refers to the data structure concept, while `HashMap` refers specifically to Java’s implementation.
+
## Strengths:
- **Fast lookups**: Lookups take O(1) time on average.
- **Flexible keys**: Most data types can be used for keys, as long as they're hashable.
diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/ImmutableHashMap.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/ImmutableHashMap.java
new file mode 100644
index 000000000000..f6e09ec623b6
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/ImmutableHashMap.java
@@ -0,0 +1,115 @@
+package com.thealgorithms.datastructures.hashmap.hashing;
+
+/**
+ * Immutable HashMap implementation using separate chaining.
+ *
+ *
+ *
+ *
+ * IMPORTANT contracts
+ *
+ *
+ *
+ *
+ *
+ * If you prefer value-based semantics, replace with HashMap
+ *
+ */
+public final class MiddleOfLinkedList {
+
+ private MiddleOfLinkedList() {
+ }
+
+ /**
+ * Returns the middle node of the list.
+ *
+ * @param head the head of the singly linked list; may be {@code null}
+ * @return the middle node (second middle for even-sized lists), or {@code null} if {@code head} is {@code null}
+ */
+ public static SinglyLinkedListNode middleNode(final SinglyLinkedListNode head) {
+ if (head == null) {
+ return null;
+ }
+
+ SinglyLinkedListNode slow = head;
+ SinglyLinkedListNode fast = head;
+
+ while (fast != null && fast.next != null) {
+ slow = slow.next;
+ fast = fast.next.next;
+ }
+
+ return slow;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/datastructures/lists/README.md b/src/main/java/com/thealgorithms/datastructures/lists/README.md
index 6aefa4c98e6d..5a0a43b923e1 100644
--- a/src/main/java/com/thealgorithms/datastructures/lists/README.md
+++ b/src/main/java/com/thealgorithms/datastructures/lists/README.md
@@ -28,5 +28,6 @@ The `next` variable points to the next node in the data structure and value stor
4. `CreateAndDetectLoop.java` : Create and detect a loop in a linked list.
5. `DoublyLinkedList.java` : A modification of singly linked list which has a `prev` pointer to point to the previous node.
6. `MergeKSortedLinkedlist.java` : Merges K sorted linked list with mergesort (mergesort is also the most efficient sorting algorithm for linked list).
-7. `RandomNode.java` : Selects a random node from given linked list and diplays it.
+7. `RandomNode.java` : Selects a random node from given linked list and displays it.
8. `SkipList.java` : Data Structure used for storing a sorted list of elements with help of a Linked list hierarchy that connects to subsequences of elements.
+9. `TortoiseHareAlgo.java` : Finds the middle element of a linked list using the fast and slow pointer (Tortoise-Hare) algorithm.
diff --git a/src/main/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgo.java b/src/main/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgo.java
new file mode 100644
index 000000000000..9d803003c658
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgo.java
@@ -0,0 +1,63 @@
+package com.thealgorithms.datastructures.lists;
+
+public class TortoiseHareAlgoRules:
+ *
+ *
+ *
+ * Example:
+ *
+ *
+ * Input tree:
+ * 1
+ * / \
+ * 2 3
+ * \
+ * 4
+ *
+ * Output string:
+ * "1(2()(4))(3)"
+ *
+ *
+ * > adj;
+ private final int[] parent;
+ private final int[] subtreeSize;
+ private final boolean[] removed;
+ private int root;
+
+ /**
+ * Constructs a centroid tree from an adjacency list.
+ *
+ * @param adj adjacency list representation of the tree (0-indexed)
+ * @throws IllegalArgumentException if tree is empty or null
+ */
+ public CentroidTree(List
> adj) {
+ if (adj == null || adj.isEmpty()) {
+ throw new IllegalArgumentException("Tree cannot be empty or null");
+ }
+
+ this.n = adj.size();
+ this.adj = adj;
+ this.parent = new int[n];
+ this.subtreeSize = new int[n];
+ this.removed = new boolean[n];
+ Arrays.fill(parent, -1);
+
+ // Build centroid tree starting from node 0
+ this.root = decompose(0, -1);
+ }
+
+ /**
+ * Recursively builds the centroid tree.
+ *
+ * @param u current node
+ * @param p parent in centroid tree
+ * @return centroid of current component
+ */
+ private int decompose(int u, int p) {
+ int size = getSubtreeSize(u, -1);
+ int centroid = findCentroid(u, -1, size);
+
+ removed[centroid] = true;
+ parent[centroid] = p;
+
+ // Recursively decompose each subtree
+ for (int v : adj.get(centroid)) {
+ if (!removed[v]) {
+ decompose(v, centroid);
+ }
+ }
+
+ return centroid;
+ }
+
+ /**
+ * Calculates subtree size from node u.
+ *
+ * @param u current node
+ * @param p parent node (-1 for root)
+ * @return size of subtree rooted at u
+ */
+ private int getSubtreeSize(int u, int p) {
+ subtreeSize[u] = 1;
+ for (int v : adj.get(u)) {
+ if (v != p && !removed[v]) {
+ subtreeSize[u] += getSubtreeSize(v, u);
+ }
+ }
+ return subtreeSize[u];
+ }
+
+ /**
+ * Finds the centroid of a subtree.
+ * A centroid is a node whose removal creates components with size <= totalSize/2.
+ *
+ * @param u current node
+ * @param p parent node
+ * @param totalSize total size of current component
+ * @return centroid node
+ */
+ private int findCentroid(int u, int p, int totalSize) {
+ for (int v : adj.get(u)) {
+ if (v != p && !removed[v] && subtreeSize[v] > totalSize / 2) {
+ return findCentroid(v, u, totalSize);
+ }
+ }
+ return u;
+ }
+
+ /**
+ * Gets the parent of a node in the centroid tree.
+ *
+ * @param node the node
+ * @return parent node in centroid tree, or -1 if root
+ */
+ public int getParent(int node) {
+ if (node < 0 || node >= n) {
+ throw new IllegalArgumentException("Invalid node: " + node);
+ }
+ return parent[node];
+ }
+
+ /**
+ * Gets the root of the centroid tree.
+ *
+ * @return root node
+ */
+ public int getRoot() {
+ return root;
+ }
+
+ /**
+ * Gets the number of nodes in the tree.
+ *
+ * @return number of nodes
+ */
+ public int size() {
+ return n;
+ }
+
+ /**
+ * Returns the centroid tree structure as a string.
+ * Format: node -> parent (or ROOT for root node)
+ *
+ * @return string representation
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("Centroid Tree:\n");
+ for (int i = 0; i < n; i++) {
+ sb.append("Node ").append(i).append(" -> ");
+ if (parent[i] == -1) {
+ sb.append("ROOT");
+ } else {
+ sb.append("Parent ").append(parent[i]);
+ }
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+ }
+
+ /**
+ * Creates a centroid tree from an edge list.
+ *
+ * @param n number of nodes (0-indexed: 0 to n-1)
+ * @param edges list of edges where each edge is [u, v]
+ * @return CentroidTree object
+ * @throws IllegalArgumentException if n <= 0 or edges is invalid
+ */
+ public static CentroidTree buildFromEdges(int n, int[][] edges) {
+ if (n <= 0) {
+ throw new IllegalArgumentException("Number of nodes must be positive");
+ }
+ if (edges == null) {
+ throw new IllegalArgumentException("Edges cannot be null");
+ }
+ if (edges.length != n - 1) {
+ throw new IllegalArgumentException("Tree must have exactly n-1 edges");
+ }
+
+ List
> adj = new ArrayList<>();
+ for (int i = 0; i < n; i++) {
+ adj.add(new ArrayList<>());
+ }
+
+ for (int[] edge : edges) {
+ if (edge.length != 2) {
+ throw new IllegalArgumentException("Each edge must have exactly 2 nodes");
+ }
+ int u = edge[0];
+ int v = edge[1];
+
+ if (u < 0 || u >= n || v < 0 || v >= n) {
+ throw new IllegalArgumentException("Invalid node in edge: [" + u + ", " + v + "]");
+ }
+
+ adj.get(u).add(v);
+ adj.get(v).add(u);
+ }
+
+ return new CentroidTree(adj);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTree.java b/src/main/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTree.java
new file mode 100644
index 000000000000..fd8876cecb70
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTree.java
@@ -0,0 +1,145 @@
+/*
+ * TheAlgorithms (https://github.com/TheAlgorithms/Java)
+ * Author: Shewale41
+ * This file is licensed under the MIT License.
+ */
+
+package com.thealgorithms.datastructures.trees;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Threaded binary tree implementation that supports insertion and
+ * in-order traversal without recursion or stack by using threads.
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+public final class Edmonds {
+
+ private Edmonds() {
+ }
+
+ /**
+ * Represents a directed weighted edge in the graph.
+ */
+ public static class Edge {
+ final int from;
+ final int to;
+ final long weight;
+
+ /**
+ * Constructs a directed edge.
+ *
+ * @param from source vertex
+ * @param to destination vertex
+ * @param weight edge weight
+ */
+ public Edge(int from, int to, long weight) {
+ this.from = from;
+ this.to = to;
+ this.weight = weight;
+ }
+ }
+
+ /**
+ * Computes the total weight of the Minimum Spanning Arborescence of a directed,
+ * weighted graph from a given root.
+ *
+ * @param numVertices the number of vertices, labeled {@code 0..numVertices-1}
+ * @param edges list of directed edges in the graph
+ * @param root the root vertex
+ * @return the total weight of the MSA. Returns -1 if not all vertices are reachable
+ * from the root or if a valid arborescence cannot be formed.
+ * @throws IllegalArgumentException if {@code numVertices <= 0} or {@code root} is out of range.
+ */
+ public static long findMinimumSpanningArborescence(int numVertices, List
+ *
+ *
+ * 1. Compute indegree and outdegree for all vertices.
+ * 2. Check if the graph satisfies Eulerian path or circuit conditions.
+ * 3. Verify that all vertices with non-zero degree are weakly connected (undirected connectivity).
+ * 4. Use Hierholzer’s algorithm to build the path by exploring unused edges iteratively.
+ *
+ * Space Complexity: O(V + E).
+ * > adjacencyList;
+
+ /**
+ * Constructs a graph with a given number of vertices.
+ *
+ * @param numNodes number of vertices
+ */
+ public Graph(int numNodes) {
+ adjacencyList = new ArrayList<>();
+ for (int i = 0; i < numNodes; i++) {
+ adjacencyList.add(new ArrayList<>());
+ }
+ }
+
+ /**
+ * Adds a directed edge from vertex {@code from} to vertex {@code to}.
+ *
+ * @param from source vertex
+ * @param to destination vertex
+ */
+ public void addEdge(int from, int to) {
+ adjacencyList.get(from).add(to);
+ }
+
+ /**
+ * Returns a list of outgoing edges from the given vertex.
+ *
+ * @param node vertex index
+ * @return list of destination vertices
+ */
+ public List
> kShortestPaths(int[][] weights, int src, int dst, int k) {
+ validate(weights, src, dst, k);
+ final int n = weights.length;
+ // Make a defensive copy to avoid mutating caller's matrix
+ int[][] weightsCopy = new int[n][n];
+ for (int i = 0; i < n; i++) {
+ weightsCopy[i] = Arrays.copyOf(weights[i], n);
+ }
+
+ List
> result = new ArrayList<>(shortestPaths.size());
+ for (Path p : shortestPaths) {
+ result.add(new ArrayList<>(p.nodes));
+ }
+ return result;
+ }
+
+ private static void validate(int[][] weights, int src, int dst, int k) {
+ if (weights == null || weights.length == 0) {
+ throw new IllegalArgumentException("Weights matrix must not be null or empty");
+ }
+ int n = weights.length;
+ for (int i = 0; i < n; i++) {
+ if (weights[i] == null || weights[i].length != n) {
+ throw new IllegalArgumentException("Weights matrix must be square");
+ }
+ for (int j = 0; j < n; j++) {
+ int val = weights[i][j];
+ if (val < NO_EDGE) {
+ throw new IllegalArgumentException("Weights must be -1 (no edge) or >= 0");
+ }
+ }
+ }
+ if (src < 0 || dst < 0 || src >= n || dst >= n) {
+ throw new IllegalArgumentException("Invalid src/dst indices");
+ }
+ if (k < 1) {
+ throw new IllegalArgumentException("k must be >= 1");
+ }
+ }
+
+ private static boolean startsWith(List