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..101d82427e38 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
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 13d1fe39c168..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)
@@ -672,6 +754,7 @@
- 📄 [PancakeSort](src/main/java/com/thealgorithms/sorts/PancakeSort.java)
- 📄 [PatienceSort](src/main/java/com/thealgorithms/sorts/PatienceSort.java)
- 📄 [PigeonholeSort](src/main/java/com/thealgorithms/sorts/PigeonholeSort.java)
+ - 📄 [PriorityQueueSort](src/main/java/com/thealgorithms/sorts/PriorityQueueSort.java)
- 📄 [QuickSort](src/main/java/com/thealgorithms/sorts/QuickSort.java)
- 📄 [RadixSort](src/main/java/com/thealgorithms/sorts/RadixSort.java)
- 📄 [SelectionSort](src/main/java/com/thealgorithms/sorts/SelectionSort.java)
@@ -714,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)
@@ -724,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)
@@ -748,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**
@@ -762,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)
@@ -773,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)
@@ -823,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)
@@ -834,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)
@@ -860,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)
@@ -892,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)
@@ -907,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**
@@ -914,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)
@@ -922,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)
@@ -931,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)
@@ -944,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)
@@ -964,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)
@@ -982,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)
@@ -1007,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)
@@ -1025,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)
@@ -1035,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)
@@ -1046,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)
@@ -1084,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)
@@ -1095,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)
@@ -1106,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)
@@ -1127,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)
@@ -1154,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)
@@ -1163,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)
@@ -1174,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)
@@ -1188,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)
@@ -1219,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**
@@ -1246,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)
@@ -1302,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)
@@ -1314,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)
@@ -1345,6 +1532,7 @@
- 📄 [PancakeSortTest](src/test/java/com/thealgorithms/sorts/PancakeSortTest.java)
- 📄 [PatienceSortTest](src/test/java/com/thealgorithms/sorts/PatienceSortTest.java)
- 📄 [PigeonholeSortTest](src/test/java/com/thealgorithms/sorts/PigeonholeSortTest.java)
+ - 📄 [PriorityQueueSortTest](src/test/java/com/thealgorithms/sorts/PriorityQueueSortTest.java)
- 📄 [QuickSortTest](src/test/java/com/thealgorithms/sorts/QuickSortTest.java)
- 📄 [RadixSortTest](src/test/java/com/thealgorithms/sorts/RadixSortTest.java)
- 📄 [SelectionSortRecursiveTest](src/test/java/com/thealgorithms/sorts/SelectionSortRecursiveTest.java)
@@ -1386,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)
@@ -1396,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)
@@ -1418,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/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 14a0375fe170..59a497427c0d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@
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
- * 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/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 HashMapRules:
+ *
+ *
+ *
+ * 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