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..1c2c1ef828b7 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:
@@ -20,7 +20,7 @@ jobs:
if: >-
github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name != github.repository
- uses: codecov/codecov-action@v5
+ uses: codecov/codecov-action@v6
with:
fail_ci_if_error: true
- name: Upload coverage to codecov (with token)
@@ -28,7 +28,7 @@ jobs:
github.repository == 'TheAlgorithms/Java' &&
(github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name == github.repository)
- uses: codecov/codecov-action@v5
+ uses: codecov/codecov-action@v6
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
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
index 6deea88f0daf..4013e87b6569 100644
--- a/.github/workflows/close-failed-prs.yml
+++ b/.github/workflows/close-failed-prs.yml
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Close stale PRs
- uses: actions/github-script@v8
+ uses: actions/github-script@v9
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 3a4cfd829b6b..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
@@ -52,7 +52,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
diff --git a/.github/workflows/infer.yml b/.github/workflows/infer.yml
index 3df7c4b1fc9e..9d4dcf63000b 100644
--- a/.github/workflows/infer.yml
+++ b/.github/workflows/infer.yml
@@ -15,7 +15,7 @@ jobs:
run_infer:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- name: Set up JDK
uses: actions/setup-java@v5
@@ -33,7 +33,7 @@ jobs:
- name: Cache infer build
id: cache-infer
- uses: actions/cache@v4
+ uses: actions/cache@v5
with:
path: infer
key: ${{ runner.os }}-infer-${{ env.year_week }}
@@ -44,7 +44,7 @@ jobs:
cd ..
git clone https://github.com/facebook/infer.git
cd infer
- git checkout 01aaa268f9d38723ba69c139e10f9e2a04b40b1c
+ git checkout 02c2c43b71e4c5110c0be841e66153942fda06c9
./build-infer.sh java
cp -r infer ../Java
diff --git a/.github/workflows/project_structure.yml b/.github/workflows/project_structure.yml
index f9fb82a2781c..5aadc6353791 100644
--- a/.github/workflows/project_structure.yml
+++ b/.github/workflows/project_structure.yml
@@ -15,7 +15,7 @@ jobs:
check_structure:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.13'
diff --git a/.github/workflows/update-directorymd.yml b/.github/workflows/update-directorymd.yml
index 6692a884a867..1cfee6e36e4e 100644
--- a/.github/workflows/update-directorymd.yml
+++ b/.github/workflows/update-directorymd.yml
@@ -1,4 +1,4 @@
-name: Generate Directory Markdown
+ο»Ώname: Generate Directory Markdown
on:
push:
@@ -14,7 +14,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
- name: Run Directory Tree Generator
uses: DenizAltunkapan/directory-tree-generator@v2
@@ -31,7 +33,7 @@ jobs:
git diff --cached --quiet || git commit -m "Update DIRECTORY.md"
- name: Create Pull Request
- uses: peter-evans/create-pull-request@v7
+ uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.REPO_SCOPED_TOKEN }}
branch: update-directory
diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile
index 4195f928d1bc..a8951da7de26 100644
--- a/.gitpod.dockerfile
+++ b/.gitpod.dockerfile
@@ -1,4 +1,4 @@
-FROM gitpod/workspace-java-21:2025-10-06-13-14-25
+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 eca2453fad0f..37d9b3c295e2 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,11 +24,14 @@
- π [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)
@@ -76,6 +80,7 @@
- π [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)
@@ -93,6 +98,12 @@
- π [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**
@@ -125,6 +136,7 @@
- π [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)
@@ -173,7 +185,6 @@
- π [FordFulkerson](src/main/java/com/thealgorithms/datastructures/graphs/FordFulkerson.java)
- π [Graphs](src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java)
- π [HamiltonianCycle](src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java)
- - π [HierholzerAlgorithm](src/main/java/com/thealgorithms/graph/HierholzerAlgorithm.java)
- π [JohnsonsAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/JohnsonsAlgorithm.java)
- π [KahnsAlgorithm](src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java)
- π [Kosaraju](src/main/java/com/thealgorithms/datastructures/graphs/Kosaraju.java)
@@ -190,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)
@@ -201,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)
@@ -255,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)
@@ -276,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)
@@ -358,8 +374,10 @@
- π [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)
@@ -372,10 +390,14 @@
- π [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)
@@ -409,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)
@@ -420,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)
@@ -434,10 +458,11 @@
- π [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)
@@ -471,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)
@@ -478,6 +504,7 @@
- π [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)
@@ -493,6 +520,7 @@
- π [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**
@@ -511,6 +539,7 @@
- π [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)
@@ -531,6 +560,7 @@
- π [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)
@@ -539,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**
@@ -591,17 +622,22 @@
- π [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**
@@ -613,6 +649,7 @@
- π [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)
@@ -649,7 +686,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)
@@ -662,7 +699,6 @@
- π [LowerBound](src/main/java/com/thealgorithms/searches/LowerBound.java)
- π [MonteCarloTreeSearch](src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java)
- π [OrderAgnosticBinarySearch](src/main/java/com/thealgorithms/searches/OrderAgnosticBinarySearch.java)
- - π [PerfectBinarySearch](src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java)
- π [QuickSelect](src/main/java/com/thealgorithms/searches/QuickSelect.java)
- π [RabinKarpAlgorithm](src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java)
- π [RandomSearch](src/main/java/com/thealgorithms/searches/RandomSearch.java)
@@ -671,7 +707,6 @@
- π [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)
- π [UnionFind](src/main/java/com/thealgorithms/searches/UnionFind.java)
@@ -758,6 +793,8 @@
- π [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)
@@ -772,13 +809,14 @@
- π [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)
- - π [LongestPalindromicSubstring](src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java)
- π [Lower](src/main/java/com/thealgorithms/strings/Lower.java)
- π [Manacher](src/main/java/com/thealgorithms/strings/Manacher.java)
- π [MyAtoi](src/main/java/com/thealgorithms/strings/MyAtoi.java)
+ - π [MoveHashToEnd](src/main/java/com/thealgorithms/strings/MoveHashToEnd.java)
- π [Palindrome](src/main/java/com/thealgorithms/strings/Palindrome.java)
- π [Pangram](src/main/java/com/thealgorithms/strings/Pangram.java)
- π [PermuteString](src/main/java/com/thealgorithms/strings/PermuteString.java)
@@ -792,8 +830,8 @@
- π [StringMatchFiniteAutomata](src/main/java/com/thealgorithms/strings/StringMatchFiniteAutomata.java)
- π [SuffixArray](src/main/java/com/thealgorithms/strings/SuffixArray.java)
- π [Upper](src/main/java/com/thealgorithms/strings/Upper.java)
- - π [ValidParentheses](src/main/java/com/thealgorithms/strings/ValidParentheses.java)
- π [WordLadder](src/main/java/com/thealgorithms/strings/WordLadder.java)
+ - π [ZAlgorithm](src/main/java/com/thealgorithms/strings/ZAlgorithm.java)
- π **zigZagPattern**
- π [ZigZagPattern](src/main/java/com/thealgorithms/strings/zigZagPattern/ZigZagPattern.java)
- π **tree**
@@ -808,6 +846,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)
@@ -819,11 +858,14 @@
- π [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)
@@ -871,6 +913,7 @@
- π [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)
@@ -884,6 +927,12 @@
- π [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**
@@ -914,6 +963,7 @@
- π [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)
@@ -947,8 +997,10 @@
- π [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)
@@ -971,6 +1023,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)
@@ -979,6 +1032,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)
@@ -1028,8 +1082,10 @@
- π [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)
@@ -1043,6 +1099,7 @@
- π [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)
@@ -1114,8 +1171,10 @@
- π [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)
@@ -1128,9 +1187,14 @@
- π [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)
@@ -1161,6 +1225,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)
@@ -1172,6 +1237,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)
@@ -1185,8 +1251,9 @@
- π [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)
@@ -1211,6 +1278,7 @@
- π [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)
@@ -1220,12 +1288,14 @@
- π [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)
@@ -1240,6 +1310,7 @@
- π [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)
@@ -1249,6 +1320,7 @@
- π [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)
@@ -1275,14 +1347,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)
@@ -1316,22 +1390,26 @@
- π [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**
@@ -1343,6 +1421,7 @@
- π [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)
@@ -1392,7 +1471,6 @@
- π [LowerBoundTest](src/test/java/com/thealgorithms/searches/LowerBoundTest.java)
- π [MonteCarloTreeSearchTest](src/test/java/com/thealgorithms/searches/MonteCarloTreeSearchTest.java)
- π [OrderAgnosticBinarySearchTest](src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java)
- - π [PerfectBinarySearchTest](src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java)
- π [QuickSelectTest](src/test/java/com/thealgorithms/searches/QuickSelectTest.java)
- π [RabinKarpAlgorithmTest](src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java)
- π [RandomSearchTest](src/test/java/com/thealgorithms/searches/RandomSearchTest.java)
@@ -1401,7 +1479,6 @@
- π [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)
- π [TestSearchInARowAndColWiseSortedMatrix](src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java)
@@ -1487,6 +1564,8 @@
- π [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)
@@ -1500,10 +1579,10 @@
- π [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)
- - π [LongestPalindromicSubstringTest](src/test/java/com/thealgorithms/strings/LongestPalindromicSubstringTest.java)
- π [LowerTest](src/test/java/com/thealgorithms/strings/LowerTest.java)
- π [ManacherTest](src/test/java/com/thealgorithms/strings/ManacherTest.java)
- π [MyAtoiTest](src/test/java/com/thealgorithms/strings/MyAtoiTest.java)
@@ -1519,8 +1598,8 @@
- π [StringMatchFiniteAutomataTest](src/test/java/com/thealgorithms/strings/StringMatchFiniteAutomataTest.java)
- π [SuffixArrayTest](src/test/java/com/thealgorithms/strings/SuffixArrayTest.java)
- π [UpperTest](src/test/java/com/thealgorithms/strings/UpperTest.java)
- - π [ValidParenthesesTest](src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java)
- π [WordLadderTest](src/test/java/com/thealgorithms/strings/WordLadderTest.java)
+ - π [ZAlgorithmTest](src/test/java/com/thealgorithms/strings/ZAlgorithmTest.java)
- π **zigZagPattern**
- π [ZigZagPatternTest](src/test/java/com/thealgorithms/strings/zigZagPattern/ZigZagPatternTest.java)
- π **tree**
diff --git a/README-ko.md b/README-ko.md
deleted file mode 100644
index 4f8cab92fc42..000000000000
--- a/README-ko.md
+++ /dev/null
@@ -1,191 +0,0 @@
-# μκ³ λ¦¬μ¦ - μλ°
-
-## μ΄ [κ°λ°λΈλ°μΉ](https://github.com/TheAlgorithms/Java/tree/Development)λ κΈ°μ‘΄ νλ‘μ νΈλ₯Ό Java νλ‘μ νΈ κ΅¬μ‘°λ‘ μ¬κ°λ°νκΈ° μν΄ μμ±λμλ€. κΈ°μ¬λλ₯Ό μν΄ κ°λ° μ§μ¬λ‘ μ νν μ μλ€. μμΈν λ΄μ©μ μ΄ λ¬Έμ λ₯Ό μ°Έμ‘°νμμμ€. 컨νΈλ¦¬λ·°μ
μ μν΄ [κ°λ°λΈλ°μΉ](https://github.com/TheAlgorithms/Java/tree/Development)λ‘ μ νν μ μλ€. μμΈν λ΄μ©μ [μ΄ μ΄μ](https://github.com/TheAlgorithms/Java/issues/474)λ₯Ό μ°Έκ³ νμμμ€.
-
-### μλ°λ‘ ꡬνλ λͺ¨λ μκ³ λ¦¬μ¦λ€ (κ΅μ‘μ©)
-
-μ΄κ²λ€μ λ¨μ§ μλ²μ μν κ²μ΄λ€. νμ€ μλ° λΌμ΄λΈλ¬λ¦¬μλ μ±λ₯μμ μ΄μ λ‘ λ λμ κ²λ€μ΄ ꡬνλμ΄μλ€
-
-## μ λ ¬ μκ³ λ¦¬μ¦
-
-### Bubble(λ²λΈ μ λ ¬)
-
-![alt text][bubble-image]
-
-From [Wikipedia][bubble-wiki]: λ²λΈ μνΈ(sinking sorλΌκ³ λ λΆλ¦¬μ)λ 리μ€νΈλ₯Ό λ°λ³΅μ μΈ λ¨κ³λ‘ μ κ·Όνμ¬ μ λ ¬νλ€. κ°κ°μ μ§μ λΉκ΅νλ©°, μμκ° μλͺ»λ κ²½μ° κ·Έμ ν μμ΄ν
λ€μ μ€μνλ μκ³ λ¦¬μ¦μ΄λ€. λ μ΄μ μ€μν κ²μ΄ μμ λκΉμ§ λ°λ³΅νλ©°, λ°λ³΅μ΄ λλ¨μ 리μ€νΈκ° μ λ ¬λμμμ μλ―Ένλ€.
-
-**μμ±**
-
-- μ΅μ
μ μ±λ₯ O(n^2)
-- μ΅κ³ μ μ±λ₯ O(n)
-- νκ· μ±λ₯ O(n^2)
-
-###### View the algorithm in [action][bubble-toptal]
-
-### Insertion(μ½μ
μ λ ¬)
-
-![alt text][insertion-image]
-
-From [Wikipedia][insertion-wiki]: μ½μ
μ λ ¬μ μ΅μ’
μ λ ¬λ λ°°μ΄(λλ 리μ€νΈ)μ νλ²μ νλμ© κ΅¬μΆνλ μκ³ λ¦¬μ¦μ΄λ€. μ΄κ²μ ν° λ¦¬μ€νΈμμ λ λμ μκ³ λ¦¬μ¦μΈ ν΅ μνΈ, ν μνΈ, λλ λ¨Έμ§ μνΈλ³΄λ€ ν¨μ¬ μμ’μ ν¨μ¨μ κ°μ§λ€. κ·Έλ¦Όμμ κ° λ§λλ μ λ ¬ν΄μΌ νλ λ°°μ΄μ μμλ₯Ό λνλΈλ€. μλ¨κ³Ό λ λ²μ§Έ μλ¨ λ§λμ 첫 λ²μ§Έ κ΅μ°¨μ μμ λ°μνλ κ²μ λ λ²μ§Έ μμκ° μ²« λ²μ§Έ μμλ³΄λ€ λ λμ μ°μ μμλ₯Ό κ°μ§κΈ° λλ¬Έμ λ§λλ‘ νμλλ μ΄λ¬ν μμλ₯Ό κ΅νν κ²μ΄λ€. μ΄ λ°©λ²μ λ°λ³΅νλ©΄ μ½μ
μ λ ¬μ΄ μλ£λλ€.
-
-**μμ±**
-
-- μ΅μ
μ μ±λ₯ O(n^2)
-- μ΅κ³ μ μ±λ₯ O(n)
-- νκ· O(n^2)
-
-###### View the algorithm in [action][insertion-toptal]
-
-### Merge(ν©λ³ μ λ ¬)
-
-![alt text][merge-image]
-
-From [Wikipedia][merge-wiki]: μ»΄ν¨ν° κ³Όνμμ, ν©λ³ μ λ ¬μ ν¨μ¨μ μΈ, λ²μ©μ μΈ, λΉκ΅ κΈ°λ° μ λ ¬ μκ³ λ¦¬μ¦μ΄λ€. λλΆλΆμ ꡬνμ μμ μ μΈ λΆλ₯λ₯Ό μ΄λ£¨λλ°, μ΄κ²μ ꡬνμ΄ μ λ ¬λ μΆλ ₯μ λμΌν μμμ μ
λ ₯ μμλ₯Ό μ μ§νλ€λ κ²μ μλ―Ένλ€. ν©λ³ μ λ ¬μ 1945λ
μ John von Neumannμ΄ λ°λͺ
ν λΆν μ 볡 μκ³ λ¦¬μ¦μ΄λ€.
-
-**μμ±**
-
-- μ΅μ
μ μ±λ₯ O(n log n) (μΌλ°μ )
-- μ΅κ³ μ μ±λ₯ O(n log n)
-- νκ· O(n log n)
-
-###### View the algorithm in [action][merge-toptal]
-
-### Quick(ν΅ μ λ ¬)
-
-![alt text][quick-image]
-
-From [Wikipedia][quick-wiki]: ν΅ μ λ ¬sometimes called partition-exchange sort)μ ν¨μ¨μ μΈ μ λ ¬ μκ³ λ¦¬μ¦μΌλ‘, λ°°μ΄μ μμλ₯Ό μμλλ‘ μ λ ¬νλ 체κ³μ μΈ λ°©λ² μνμ νλ€.
-
-**μμ±**
-
-- μ΅μ
μ μ±λ₯ O(n^2)
-- μ΅κ³ μ μ±λ₯ O(n log n) or O(n) with three-way partition
-- νκ· O(n log n)
-
-###### View the algorithm in [action][quick-toptal]
-
-### Selection(μ ν μ λ ¬)
-
-![alt text][selection-image]
-
-From [Wikipedia][selection-wiki]: μκ³ λ¦¬μ¦ μ
λ ₯ 리μ€νΈλ₯Ό λ λΆλΆμΌλ‘ λλλ€ : 첫 λΆλΆμ μμ΄ν
λ€μ΄ μ΄λ―Έ μΌμͺ½μμ μ€λ₯Έμͺ½μΌλ‘ μ λ ¬λμλ€. κ·Έλ¦¬κ³ λ¨μ λΆλΆμ μμ΄ν
λ€μ λλ¨Έμ§ νλͺ©μ μ°¨μ§νλ 리μ€νΈμ΄λ€. μ²μμλ μ λ ¬λ 리μ€νΈλ 곡백μ΄κ³ λλ¨Έμ§κ° μ λΆμ΄λ€. μ€λ₯΄μ°¨μ(λλ λ΄λ¦Όμ°¨μ) μκ³ λ¦¬μ¦μ κ°μ₯ μμ μμλ₯Ό μ λ ¬λμ§ μμ 리μ€νΈμμ μ°Ύκ³ μ λ ¬μ΄ μλ κ°μ₯ μΌμͺ½(μ λ ¬λ 리μ€νΈ) 리μ€νΈμ λ°κΎΌλ€. μ΄λ κ² μ€λ₯Έμͺ½μΌλ‘ λμκ°λ€.
-
-**μμ±**
-
-- μ΅μ
μ μ±λ₯ O(n^2)
-- μ΅κ³ μ μ±λ₯ O(n^2)
-- νκ· O(n^2)
-
-###### View the algorithm in [action][selection-toptal]
-
-### Shell(μ μ λ ¬)
-
-![alt text][shell-image]
-
-From [Wikipedia][shell-wiki]: μ μ λ ¬μ λ©λ¦¬ λ¨μ΄μ Έ μλ νλͺ©μ κ΅νμ νμ©νλ μ½μ
μ’
λ₯μ μΌλ°νμ΄λ€. κ·Έ μμ΄λμ΄λ λͺ¨λ nλ²μ§Έ μμκ° μ λ ¬λ λͺ©λ‘μ μ 곡νλ€λ κ²μ κ³ λ €νμ¬ μ΄λ κ³³μμλ μ§ μμνλλ‘ μμμ λͺ©λ‘μ λ°°μ΄νλ κ²μ΄λ€. μ΄λ¬ν λͺ©λ‘μ h-sortedλ‘ μλ €μ Έ μλ€. λ§μ°¬κ°μ§λ‘, κ°κ° κ°λ³μ μΌλ‘ μ λ ¬λ h μΈν°λ¦¬λΈ λͺ©λ‘μΌλ‘ κ°μ£Όν μ μλ€.
-
-**μμ±**
-
-- μ΅μ
μ μ±λ₯ O(nlog2 2n)
-- μ΅κ³ μ μ±λ₯ O(n log n)
-- Average case performance depends on gap sequence
-
-###### View the algorithm in [action][shell-toptal]
-
-### μκ° λ³΅μ‘μ± κ·Έλν
-
-μ λ ¬ μκ³ λ¦¬μ¦μ 볡μ‘μ± λΉκ΅ (λ²λΈ μ λ ¬, μ½μ
μ λ ¬, μ ν μ λ ¬)
-
-[볡μ‘μ± κ·Έλν](https://github.com/prateekiiest/Python/blob/master/sorts/sortinggraphs.png)
-
----
-
-## κ²μ μκ³ λ¦¬μ¦
-
-### Linear (μ ν νμ)
-
-![alt text][linear-image]
-
-From [Wikipedia][linear-wiki]: μ ν νμ λλ μμ°¨ νμμ λͺ©λ‘ λ΄μμ λͺ©νκ°μ μ°Ύλ λ°©λ²μ΄λ€. μΌμΉ νλͺ©μ΄ λ°κ²¬λκ±°λ λͺ¨λ μμκ° νμλ λκΉμ§ λͺ©λ‘μ κ° μμμ λν΄ λͺ©νκ°μ μμ°¨μ μΌλ‘ κ²μ¬νλ€.
-μ ν κ²μμ μ΅μ
μ μ ν μκ°μΌλ‘ μ€νλλ©° μ΅λ nκ°μ λΉκ΅μμ μ΄λ£¨μ΄μ§λ€. μ¬κΈ°μ nμ λͺ©λ‘μ κΈΈμ΄λ€.
-
-**μμ±**
-
-- μ΅μ
μ μ±λ₯ O(n)
-- μ΅κ³ μ μ±λ₯ O(1)
-- νκ· O(n)
-- μ΅μ
μ κ²½μ° κ³΅κ° λ³΅μ‘μ± O(1) iterative
-
-### Binary (μ΄μ§ νμ)
-
-![alt text][binary-image]
-
-From [Wikipedia][binary-wiki]: μ΄μ§ νμ, (also known as half-interval search or logarithmic search), μ μ λ ¬λ λ°°μ΄ λ΄μμ λͺ©νκ°μ μμΉλ₯Ό μ°Ύλ κ²μ μκ³ λ¦¬μ¦μ΄λ€. λͺ©νκ°μ λ°°μ΄μ μ€κ° μμμ λΉκ΅νλ€; λ§μ½ λͺ©νκ°μ΄ λμΌνμ§ μμΌλ©΄, λͺ©νλ¬Όμ μ λ°μ΄ μ κ±°λκ³ κ²μμ΄ μ±κ³΅ν λκΉμ§ λλ¨Έμ§ μ λ°μμ μλλ€.
-
-**μμ±**
-
-- μ΅μ
μ μ±λ₯ O(log n)
-- μ΅κ³ μ μ±λ₯ O(1)
-- νκ· O(log n)
-- μ΅μ
μ κ²½μ° κ³΅κ° λ³΅μ‘μ± O(1)
-
-[bubble-toptal]: https://www.toptal.com/developers/sorting-algorithms/bubble-sort
-[bubble-wiki]: https://en.wikipedia.org/wiki/Bubble_sort
-[bubble-image]: https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Bubblesort-edited-color.svg/220px-Bubblesort-edited-color.svg.png "Bubble Sort"
-[insertion-toptal]: https://www.toptal.com/developers/sorting-algorithms/insertion-sort
-[insertion-wiki]: https://en.wikipedia.org/wiki/Insertion_sort
-[insertion-image]: https://upload.wikimedia.org/wikipedia/commons/7/7e/Insertionsort-edited.png "Insertion Sort"
-[quick-toptal]: https://www.toptal.com/developers/sorting-algorithms/quick-sort
-[quick-wiki]: https://en.wikipedia.org/wiki/Quicksort
-[quick-image]: https://upload.wikimedia.org/wikipedia/commons/6/6a/Sorting_quicksort_anim.gif "Quick Sort"
-[merge-toptal]: https://www.toptal.com/developers/sorting-algorithms/merge-sort
-[merge-wiki]: https://en.wikipedia.org/wiki/Merge_sort
-[merge-image]: https://upload.wikimedia.org/wikipedia/commons/c/cc/Merge-sort-example-300px.gif "Merge Sort"
-[selection-toptal]: https://www.toptal.com/developers/sorting-algorithms/selection-sort
-[selection-wiki]: https://en.wikipedia.org/wiki/Selection_sort
-[selection-image]: https://upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Selection_sort_animation.gif/250px-Selection_sort_animation.gif "Selection Sort Sort"
-[shell-toptal]: https://www.toptal.com/developers/sorting-algorithms/shell-sort
-[shell-wiki]: https://en.wikipedia.org/wiki/Shellsort
-[shell-image]: https://upload.wikimedia.org/wikipedia/commons/d/d8/Sorting_shellsort_anim.gif "Shell Sort"
-[linear-wiki]: https://en.wikipedia.org/wiki/Linear_search
-[linear-image]: http://www.tutorialspoint.com/data_structures_algorithms/images/linear_search.gif
-[binary-wiki]: https://en.wikipedia.org/wiki/Binary_search_algorithm
-[binary-image]: https://upload.wikimedia.org/wikipedia/commons/f/f7/Binary_search_into_array.png
-
----
-
-## λλ¨Έμ§ μκ³ λ¦¬μ¦μ λν λ§ν¬
-
-| μ ν | λ€μ΄λλ―Ήνλ‘κ·Έλλ°(DP) | μνΈ | κ·Έ μΈ κ²λ€ |
-| --------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------ |
-| [Any Base to Any Base](Conversions/AnyBaseToAnyBase.java) | [Coin Change](DynamicProgramming/CoinChange.java) | [Caesar](Ciphers/Caesar.java) | [Heap Sort](Sorts/HeapSort.java) |
-| [Any Base to Decimal](Conversions/AnyBaseToDecimal.java) | [Egg Dropping](DynamicProgramming/EggDropping.java) | [Columnar Transposition Cipher](Ciphers/ColumnarTranspositionCipher.java) | [Palindromic Prime Checker](Misc/PalindromePrime.java) |
-| [Binary to Decimal](Conversions/BinaryToDecimal.java) | [Fibonacci](DynamicProgramming/Fibonacci.java) | [RSA](Ciphers/RSA.java) | More soon... |
-| [Binary to HexaDecimal](Conversions/BinaryToHexadecimal.java) | [Kadane Algorithm](DynamicProgramming/KadaneAlgorithm.java) | more coming soon... |
-| [Binary to Octal](Conversions/BinaryToOctal.java) | [Knapsack](DynamicProgramming/Knapsack.java) |
-| [Decimal To Any Base](Conversions/DecimalToAnyBase.java) | [Longest Common Subsequence](DynamicProgramming/LongestCommonSubsequence.java) |
-| [Decimal To Binary](Conversions/DecimalToBinary.java) | [Longest Increasing Subsequence](DynamicProgramming/LongestIncreasingSubsequence.java) |
-| [Decimal To Hexadecimal](Conversions/DecimalToHexaDecimal.java) | [Rod Cutting](DynamicProgramming/RodCutting.java) |
-| and much more... | and more... |
-
-### μλ£ κ΅¬μ‘°
-
-| κ·Έλν | ν | 리μ€νΈ | ν |
-| ------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------- |
-| | [λΉ ν μμΈμ²λ¦¬](DataStructures/Heaps/EmptyHeapException.java) | [μν μ°κ²°λ¦¬μ€νΈ](DataStructures/Lists/CircleLinkedList.java) | [μ λλ¦ μ΄λ μ΄ λ¦¬μ€νΈ ν](DataStructures/Queues/GenericArrayListQueue.java) |
-| | [ν](DataStructures/Heaps/Heap.java) | [μ΄μ€ μ°κ²°λ¦¬μ€νΈ](DataStructures/Lists/DoublyLinkedList.java) | [ν](DataStructures/Queues/Queues.java) |
-| [κ·Έλν](DataStructures/Graphs/Graphs.java) | [ν μμ](DataStructures/Heaps/HeapElement.java) | [λ¨μ μ°κ²°λ¦¬μ€νΈ](DataStructures/Lists/SinglyLinkedList.java) |
-| [ν¬λ£¨μ€μΉΌ μκ³ λ¦¬μ¦](DataStructures/Graphs/Kruskal.java) | [μ΅λν](DataStructures/Heaps/MaxHeap.java) |
-| [νλ ¬ κ·Έλν](DataStructures/Graphs/MatrixGraphs.java) | [μ΅μν](DataStructures/Heaps/MinHeap.java) |
-| [νλ¦Ό μ΅μμ μ₯νΈλ¦¬](DataStructures/Graphs/PrimMST.java) |
-
-| μ€ν | νΈλ¦¬ |
-| --------------------------------------------------------------- | ------------------------------------------------- |
-| [λ
Έλ μ€ν](DataStructures/Stacks/NodeStack.java) | [AVL νΈλ¦¬](DataStructures/Trees/AVLTree.java) |
-| [μ°κ²°λ¦¬μ€νΈ μ€ν](DataStructures/Stacks/StackOfLinkedList.java) | [μ΄μ§ νΈλ¦¬](DataStructures/Trees/BinaryTree.java) |
-| [μ€ν](DataStructures/Stacks) | And much more... |
-
-- [Bags](DataStructures/Bags/Bag.java)
-- [Buffer](DataStructures/Buffers/CircularBuffer.java)
-- [HashMap](DataStructures/HashMap/Hashing/HashMap.java)
--
diff --git a/pmd-exclude.properties b/pmd-exclude.properties
index a3c95b12fa4b..64562c524728 100644
--- a/pmd-exclude.properties
+++ b/pmd-exclude.properties
@@ -53,14 +53,11 @@ com.thealgorithms.maths.Gaussian=UselessParentheses
com.thealgorithms.maths.GcdSolutionWrapper=UselessParentheses
com.thealgorithms.maths.HeronsFormula=UselessParentheses
com.thealgorithms.maths.JugglerSequence=UselessMainMethod
-com.thealgorithms.maths.KaprekarNumbers=UselessParentheses
com.thealgorithms.maths.KeithNumber=UselessMainMethod,UselessParentheses
-com.thealgorithms.maths.LeonardoNumber=UselessParentheses
com.thealgorithms.maths.LinearDiophantineEquationsSolver=UselessMainMethod,UselessParentheses
com.thealgorithms.maths.MagicSquare=UselessMainMethod
com.thealgorithms.maths.PiNilakantha=UselessMainMethod
com.thealgorithms.maths.Prime.PrimeCheck=UselessMainMethod
-com.thealgorithms.maths.PythagoreanTriple=UselessMainMethod
com.thealgorithms.maths.RomanNumeralUtil=UselessParentheses
com.thealgorithms.maths.SecondMinMax=UselessParentheses
com.thealgorithms.maths.SecondMinMaxTest=UnnecessaryFullyQualifiedName
@@ -71,7 +68,6 @@ com.thealgorithms.maths.TrinomialTriangle=UselessMainMethod,UselessParentheses
com.thealgorithms.maths.VectorCrossProduct=UselessMainMethod
com.thealgorithms.maths.Volume=UselessParentheses
com.thealgorithms.matrix.RotateMatrixBy90Degrees=UselessMainMethod
-com.thealgorithms.misc.Sparsity=UselessParentheses
com.thealgorithms.others.BankersAlgorithm=UselessMainMethod
com.thealgorithms.others.BrianKernighanAlgorithm=UselessMainMethod
com.thealgorithms.others.CRC16=UselessMainMethod,UselessParentheses
@@ -79,11 +75,9 @@ com.thealgorithms.others.CRC32=UselessMainMethod
com.thealgorithms.others.Damm=UnnecessaryFullyQualifiedName,UselessMainMethod
com.thealgorithms.others.Dijkstra=UselessMainMethod
com.thealgorithms.others.GaussLegendre=UselessMainMethod
-com.thealgorithms.others.HappyNumbersSeq=UselessMainMethod
com.thealgorithms.others.Huffman=UselessMainMethod
com.thealgorithms.others.InsertDeleteInArray=UselessMainMethod
com.thealgorithms.others.KochSnowflake=UselessMainMethod
-com.thealgorithms.others.Krishnamurthy=UselessMainMethod
com.thealgorithms.others.LinearCongruentialGenerator=UselessMainMethod
com.thealgorithms.others.Luhn=UnnecessaryFullyQualifiedName,UselessMainMethod
com.thealgorithms.others.Mandelbrot=UselessMainMethod,UselessParentheses
@@ -94,7 +88,6 @@ 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
@@ -108,15 +101,11 @@ com.thealgorithms.sorts.MergeSortNoExtraSpace=UselessParentheses
com.thealgorithms.sorts.RadixSort=UselessParentheses
com.thealgorithms.sorts.TreeSort=UselessMainMethod
com.thealgorithms.sorts.WiggleSort=UselessParentheses
-com.thealgorithms.stacks.LargestRectangle=UselessMainMethod
com.thealgorithms.stacks.MaximumMinimumWindow=UselessMainMethod
com.thealgorithms.stacks.PostfixToInfix=UselessParentheses
-com.thealgorithms.strings.Alphabetical=UselessMainMethod
com.thealgorithms.strings.HorspoolSearch=UnnecessaryFullyQualifiedName,UselessParentheses
-com.thealgorithms.strings.KMP=UselessMainMethod
com.thealgorithms.strings.Lower=UselessMainMethod
com.thealgorithms.strings.Palindrome=UselessParentheses
com.thealgorithms.strings.Pangram=UselessMainMethod
-com.thealgorithms.strings.RabinKarp=UselessMainMethod
com.thealgorithms.strings.Rotation=UselessMainMethod
com.thealgorithms.strings.Upper=UselessMainMethod
diff --git a/pom.xml b/pom.xml
index 7e936967208b..e0a3486b23bb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,7 +12,7 @@
This filter applies an exponential moving average to a sequence of audio
+ *
+ * This filter applies an exponential moving average to a sequence of audio
* signal values, making it useful for smoothing out rapid fluctuations.
* The smoothing factor (alpha) controls the degree of smoothing.
*
- * Based on the definition from
+ *
+ * Based on the definition from
* Wikipedia link.
*/
public class EMAFilter {
private final double alpha;
private double emaValue;
+
/**
* Constructs an EMA filter with a given smoothing factor.
*
@@ -26,14 +29,17 @@ public EMAFilter(double alpha) {
this.alpha = alpha;
this.emaValue = 0.0;
}
+
/**
* Applies the EMA filter to an audio signal array.
+ * EMA formula:
+ * EMA = alpha * currentSample + (1 - alpha) * previousEMA
*
* @param audioSignal Array of audio samples to process
* @return Array of processed (smoothed) samples
*/
public double[] apply(double[] audioSignal) {
- if (audioSignal.length == 0) {
+ if (audioSignal == null || audioSignal.length == 0) {
return new double[0];
}
double[] emaSignal = new double[audioSignal.length];
diff --git a/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java b/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java
index c35a36d97a57..269880b8ddae 100644
--- a/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java
+++ b/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java
@@ -4,11 +4,36 @@
import java.util.List;
/**
- * Program description - To find all possible paths from source to destination
- * Wikipedia
+ * Finds all possible simple paths from a given source vertex to a destination vertex
+ * in a directed graph using backtracking.
*
- * @author Siddhant Swarup Mallick
+ * This algorithm performs a Depth First Search (DFS) traversal while keeping track
+ * of visited vertices to avoid cycles. Whenever the destination vertex is reached,
+ * the current path is stored as one valid path. Key Characteristics: Time Complexity: Space Complexity: This implementation is intended for educational purposes.
+ * ElGamal is an asymmetric key encryption algorithm for public-key cryptography
+ * based on the DiffieβHellman key exchange. It relies on the difficulty
+ * of computing discrete logarithms in a cyclic group.
+ *
+ * Key Features:
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * > combination(int n, int k) {
- if (n < 0 || k < 0 || k > n) {
- throw new IllegalArgumentException("Invalid input: n must be non-negative, k must be non-negative and less than or equal to n.");
+ if (k < 0 || k > n) {
+ throw new IllegalArgumentException("Invalid input: 0 β€ k β€ n is required.");
}
List
> combinations = new ArrayList<>();
@@ -48,7 +48,7 @@ private static void combine(List
> combinations, List
> getNQueensArrangements(int queens) {
}
public static void placeQueens(final int queens) {
- List
> arrangements = new ArrayList
>();
+ List
> arrangements = new ArrayList<>();
getSolution(queens, arrangements, new int[queens], 0);
if (arrangements.isEmpty()) {
- System.out.println("There is no way to place " + queens + " queens on board of size " + queens + "x" + queens);
+ System.out.println(" no way to place " + queens + " queens on board of size " + queens + "x" + queens);
} else {
System.out.println("Arrangement for placing " + queens + " queens");
}
@@ -59,15 +76,15 @@ public static void placeQueens(final int queens) {
/**
* This is backtracking function which tries to place queen recursively
*
- * @param boardSize: size of chess board
- * @param solutions: this holds all possible arrangements
- * @param columns: columns[i] = rowId where queen is placed in ith column.
+ * @param boardSize: size of chess board
+ * @param solutions: this holds all possible arrangements
+ * @param columns: columns[i] = rowId where queen is placed in ith column.
* @param columnIndex: This is the column in which queen is being placed
*/
private static void getSolution(int boardSize, List
> solutions, int[] columns, int columnIndex) {
if (columnIndex == boardSize) {
// this means that all queens have been placed
- List
> solutions, int
// This loop tries to place queen in a row one by one
for (int rowIndex = 0; rowIndex < boardSize; rowIndex++) {
columns[columnIndex] = rowIndex;
- if (isPlacedCorrectly(columns, rowIndex, columnIndex)) {
- // If queen is placed successfully at rowIndex in column=columnIndex then try
- // placing queen in next column
- getSolution(boardSize, solutions, columns, columnIndex + 1);
- }
- }
- }
- /**
- * This function checks if queen can be placed at row = rowIndex in column =
- * columnIndex safely
- *
- * @param columns: columns[i] = rowId where queen is placed in ith column.
- * @param rowIndex: row in which queen has to be placed
- * @param columnIndex: column in which queen is being placed
- * @return true: if queen can be placed safely false: otherwise
- */
- private static boolean isPlacedCorrectly(int[] columns, int rowIndex, int columnIndex) {
- for (int i = 0; i < columnIndex; i++) {
- int diff = Math.abs(columns[i] - rowIndex);
- if (diff == 0 || columnIndex - i == diff) {
- return false;
+ // Skip current position if row or diagonal is already occupied
+ boolean isROp = OCROWS.contains(rowIndex);
+
+ boolean isDOp = OCDIAG.contains(rowIndex - columnIndex) || OCANTIDIAG.contains(rowIndex + columnIndex);
+
+ if (isROp || isDOp) {
+ continue;
}
+
+ // Mark current row and diagonal as occupied
+ OCROWS.add(rowIndex);
+ OCDIAG.add(rowIndex - columnIndex);
+ OCANTIDIAG.add(rowIndex + columnIndex);
+
+ // Move to the next column after placing current queen
+ getSolution(boardSize, solutions, columns, columnIndex + 1);
+
+ // Backtrack by removing current queen
+
+ OCROWS.remove(rowIndex);
+ OCDIAG.remove(rowIndex - columnIndex);
+ OCANTIDIAG.remove(rowIndex + columnIndex);
}
- return true;
}
}
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
+ *
+ *
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/compression/HuffmanCoding.java b/src/main/java/com/thealgorithms/compression/HuffmanCoding.java new file mode 100644 index 000000000000..d7f9d58d2429 --- /dev/null +++ b/src/main/java/com/thealgorithms/compression/HuffmanCoding.java @@ -0,0 +1,253 @@ +package com.thealgorithms.compression; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * Huffman Coding Compression Algorithm Implementation. + *
+ * Huffman Coding is a popular greedy algorithm used for lossless data compression. + * It reduces the overall size of data by assigning variable-length, prefix-free + * binary codes to input characters, ensuring that more frequent characters receive + * the shortest possible codes. + *
+ *+ * Key Features: + *
+ * Time Complexity: O(n) [or appropriate complexity] + * Space Complexity: O(n) + * @author Reshma Kakkirala + */ package com.thealgorithms.conversions; import java.util.Arrays; 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/datastructures/dynamicarray/DynamicArray.java b/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java
index cd5dc580b694..dbdb2d806209 100644
--- a/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java
+++ b/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java
@@ -63,7 +63,8 @@ public void add(final E element) {
*
* @param index the index at which the element is to be placed
* @param element the element to be inserted at the specified index
- * @throws IndexOutOfBoundsException if index is less than 0 or greater than or equal to the number of elements
+ * @throws IndexOutOfBoundsException if index is less than 0 or greater than or
+ * equal to the number of elements
*/
public void put(final int index, E element) {
if (index < 0) {
@@ -82,7 +83,8 @@ public void put(final int index, E element) {
*
* @param index the index of the element to retrieve
* @return the element at the specified index
- * @throws IndexOutOfBoundsException if index is less than 0 or greater than or equal to the current size
+ * @throws IndexOutOfBoundsException if index is less than 0 or greater than or
+ * equal to the current size
*/
@SuppressWarnings("unchecked")
public E get(final int index) {
@@ -97,7 +99,8 @@ public E get(final int index) {
*
* @param index the index of the element to be removed
* @return the element that was removed from the array
- * @throws IndexOutOfBoundsException if index is less than 0 or greater than or equal to the current size
+ * @throws IndexOutOfBoundsException if index is less than 0 or greater than or
+ * equal to the current size
*/
public E remove(final int index) {
if (index < 0 || index >= size) {
@@ -127,6 +130,21 @@ public boolean isEmpty() {
return size == 0;
}
+ /**
+ * Checks whether the array contains the specified element.
+ *
+ * @param element the element to check for
+ * @return true if the array contains the specified element, false otherwise
+ */
+ public boolean contains(final E element) {
+ for (int i = 0; i < size; i++) {
+ if (Objects.equals(elements[i], element)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Returns a sequential stream with this collection as its source.
*
@@ -137,7 +155,8 @@ public Stream 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/MiddleOfLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/MiddleOfLinkedList.java
new file mode 100644
index 000000000000..0ee788db2ff9
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/lists/MiddleOfLinkedList.java
@@ -0,0 +1,46 @@
+package com.thealgorithms.datastructures.lists;
+
+/**
+ * Returns the middle node of a singly linked list using the two-pointer technique.
+ *
+ * The {@code slow} pointer advances by one node per iteration while {@code fast} advances by two.
+ * When {@code fast == null} or {@code fast.next == null}, {@code slow} points to the middle node.
+ * For even-length lists, this returns the second middle node. This method does not modify the input list. Reference: https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare Complexity:
+ * 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.
+ *
+ * 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 The algorithm sorts the keys, preserves the corresponding search frequencies, and uses
+ * dynamic programming with Knuth's optimization to compute the minimum weighted search cost.
+ *
+ * Example: if keys = [10, 12] and frequencies = [34, 50], the best tree puts 12 at the root
+ * and 10 as its left child. The total cost is 50 * 1 + 34 * 2 = 118.
+ *
+ * Reference:
+ * https://en.wikipedia.org/wiki/Optimal_binary_search_tree
+ */
+public final class OptimalBinarySearchTree {
+ private OptimalBinarySearchTree() {
+ }
+
+ /**
+ * Computes the minimum weighted search cost for the given keys and search frequencies.
+ *
+ * @param keys the BST keys
+ * @param frequencies the search frequencies associated with the keys
+ * @return the minimum search cost
+ * @throws IllegalArgumentException if the input is invalid
+ */
+ public static long findOptimalCost(int[] keys, int[] frequencies) {
+ validateInput(keys, frequencies);
+ if (keys.length == 0) {
+ return 0L;
+ }
+
+ int[][] sortedNodes = sortNodes(keys, frequencies);
+ int nodeCount = sortedNodes.length;
+ long[] prefixSums = buildPrefixSums(sortedNodes);
+ long[][] optimalCost = new long[nodeCount][nodeCount];
+ int[][] root = new int[nodeCount][nodeCount];
+
+ // Small example:
+ // keys = [10, 12]
+ // frequencies = [34, 50]
+ // Choosing 12 as the root gives cost 50 * 1 + 34 * 2 = 118,
+ // which is better than choosing 10 as the root.
+
+ // Base case: a subtree containing one key has cost equal to its frequency,
+ // because that key becomes the root of the subtree and is searched at depth 1.
+ for (int index = 0; index < nodeCount; index++) {
+ optimalCost[index][index] = sortedNodes[index][1];
+ root[index][index] = index;
+ }
+
+ // Build solutions for longer and longer key ranges.
+ // optimalCost[start][end] stores the minimum search cost for keys in that range.
+ for (int length = 2; length <= nodeCount; length++) {
+ for (int start = 0; start <= nodeCount - length; start++) {
+ int end = start + length - 1;
+
+ // Every key in this range moves one level deeper when we choose a root,
+ // so the sum of frequencies is added once to the subtree cost.
+ long frequencySum = prefixSums[end + 1] - prefixSums[start];
+ optimalCost[start][end] = Long.MAX_VALUE;
+
+ // Knuth's optimization:
+ // the best root for [start, end] lies between the best roots of
+ // [start, end - 1] and [start + 1, end], so we search only this interval.
+ int leftBoundary = root[start][end - 1];
+ int rightBoundary = root[start + 1][end];
+ for (int currentRoot = leftBoundary; currentRoot <= rightBoundary; currentRoot++) {
+ long leftCost = currentRoot > start ? optimalCost[start][currentRoot - 1] : 0L;
+ long rightCost = currentRoot < end ? optimalCost[currentRoot + 1][end] : 0L;
+ long currentCost = frequencySum + leftCost + rightCost;
+
+ if (currentCost < optimalCost[start][end]) {
+ optimalCost[start][end] = currentCost;
+ root[start][end] = currentRoot;
+ }
+ }
+ }
+ }
+
+ return optimalCost[0][nodeCount - 1];
+ }
+
+ private static void validateInput(int[] keys, int[] frequencies) {
+ if (keys == null || frequencies == null) {
+ throw new IllegalArgumentException("Keys and frequencies cannot be null");
+ }
+ if (keys.length != frequencies.length) {
+ throw new IllegalArgumentException("Keys and frequencies must have the same length");
+ }
+
+ for (int frequency : frequencies) {
+ if (frequency < 0) {
+ throw new IllegalArgumentException("Frequencies cannot be negative");
+ }
+ }
+ }
+
+ private static int[][] sortNodes(int[] keys, int[] frequencies) {
+ int[][] sortedNodes = new int[keys.length][2];
+ for (int index = 0; index < keys.length; index++) {
+ sortedNodes[index][0] = keys[index];
+ sortedNodes[index][1] = frequencies[index];
+ }
+
+ // Sort by key so the nodes can be treated as an in-order BST sequence.
+ Arrays.sort(sortedNodes, Comparator.comparingInt(node -> node[0]));
+
+ for (int index = 1; index < sortedNodes.length; index++) {
+ if (sortedNodes[index - 1][0] == sortedNodes[index][0]) {
+ throw new IllegalArgumentException("Keys must be distinct");
+ }
+ }
+
+ return sortedNodes;
+ }
+
+ private static long[] buildPrefixSums(int[][] sortedNodes) {
+ long[] prefixSums = new long[sortedNodes.length + 1];
+ for (int index = 0; index < sortedNodes.length; index++) {
+ // prefixSums[i] holds the total frequency of the first i sorted keys.
+ // This lets us get the frequency sum of any range in O(1) time.
+ prefixSums[index + 1] = prefixSums[index] + sortedNodes[index][1];
+ }
+ return prefixSums;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/geometry/LineIntersection.java b/src/main/java/com/thealgorithms/geometry/LineIntersection.java
new file mode 100644
index 000000000000..8d65833816b3
--- /dev/null
+++ b/src/main/java/com/thealgorithms/geometry/LineIntersection.java
@@ -0,0 +1,105 @@
+package com.thealgorithms.geometry;
+
+import java.awt.geom.Point2D;
+import java.util.Optional;
+
+/**
+ * Utility methods for checking and computing 2D line segment intersections.
+ */
+public final class LineIntersection {
+ private LineIntersection() {
+ }
+
+ /**
+ * Checks whether two line segments intersect.
+ *
+ * @param p1 first endpoint of segment 1
+ * @param p2 second endpoint of segment 1
+ * @param q1 first endpoint of segment 2
+ * @param q2 second endpoint of segment 2
+ * @return true when the segments intersect (including touching endpoints)
+ */
+ public static boolean intersects(Point p1, Point p2, Point q1, Point q2) {
+ int o1 = orientation(p1, p2, q1);
+ int o2 = orientation(p1, p2, q2);
+ int o3 = orientation(q1, q2, p1);
+ int o4 = orientation(q1, q2, p2);
+
+ if (o1 != o2 && o3 != o4) {
+ return true;
+ }
+
+ if (o1 == 0 && onSegment(p1, q1, p2)) {
+ return true;
+ }
+ if (o2 == 0 && onSegment(p1, q2, p2)) {
+ return true;
+ }
+ if (o3 == 0 && onSegment(q1, p1, q2)) {
+ return true;
+ }
+ if (o4 == 0 && onSegment(q1, p2, q2)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Computes the single geometric intersection point between two non-parallel
+ * segments when it exists.
+ *
+ * For parallel/collinear overlap, this method returns {@code Optional.empty()}.
+ *
+ * @param p1 first endpoint of segment 1
+ * @param p2 second endpoint of segment 1
+ * @param q1 first endpoint of segment 2
+ * @param q2 second endpoint of segment 2
+ * @return the intersection point when uniquely defined and on both segments
+ */
+ public static Optional Input format: each account is a list where the first element is the user name and the
+ * remaining elements are emails.
+ */
+public final class AccountMerge {
+ private AccountMerge() {
+ }
+
+ public static List 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 A bridge (also called a cut-edge) is an edge in an undirected graph whose removal
+ * increases the number of connected components. Bridges represent critical links
+ * in a network β if any bridge is removed, part of the network becomes unreachable. The algorithm performs a single Depth-First Search (DFS) traversal, tracking two
+ * values for each vertex: An edge (u, v) is a bridge if and only if {@code lowLink[v] > discoveryTime[u]},
+ * meaning there is no back edge from the subtree of v that can reach u or any ancestor of u. Time Complexity: O(V + E), where V is the number of vertices and E is the number of edges. Space Complexity: O(V + E) for the adjacency list, discovery/low arrays, and recursion stack. The graph is represented as an adjacency list where each vertex is identified by
+ * an integer in the range {@code [0, vertexCount)}. For each undirected edge (u, v),
+ * v must appear in {@code adjacencyList.get(u)} and u must appear in
+ * {@code adjacencyList.get(v)}. This class provides static methods to calculate the arithmetic mean
+ * of arrays of both {@code double} and {@code int} values. It also offers
+ * a Stream-based alternative for modern, declarative usage.
+ *
+ * All methods guard against {@code null} or empty inputs.
*/
public final class Average {
@@ -13,11 +20,14 @@ private Average() {
}
/**
- * Computes the average of a {@code double} array.
+ * Computes the arithmetic mean of a {@code double} array.
+ *
+ * The average is calculated as the sum of all elements divided
+ * by the number of elements: {@code avg = Ξ£(numbers[i]) / n}.
*
- * @param numbers an array of {@code double} values
- * @return the average of the given numbers
- * @throws IllegalArgumentException if the input array is {@code null} or empty
+ * @param numbers a non-null, non-empty array of {@code double} values
+ * @return the arithmetic mean of the given numbers
+ * @throws IllegalArgumentException if {@code numbers} is {@code null} or empty
*/
public static double average(double[] numbers) {
if (numbers == null || numbers.length == 0) {
@@ -31,11 +41,14 @@ public static double average(double[] numbers) {
}
/**
- * Computes the average of an {@code int} array.
+ * Computes the arithmetic mean of an {@code int} array.
+ *
+ * The sum is accumulated in a {@code long} to prevent integer overflow
+ * when processing large arrays or large values.
*
- * @param numbers an array of {@code int} values
- * @return the average of the given numbers
- * @throws IllegalArgumentException if the input array is {@code null} or empty
+ * @param numbers a non-null, non-empty array of {@code int} values
+ * @return the arithmetic mean as a {@code long} (truncated toward zero)
+ * @throws IllegalArgumentException if {@code numbers} is {@code null} or empty
*/
public static long average(int[] numbers) {
if (numbers == null || numbers.length == 0) {
@@ -47,4 +60,21 @@ public static long average(int[] numbers) {
}
return sum / numbers.length;
}
+
+ /**
+ * Computes the arithmetic mean of a {@code double} array using Java Streams.
+ *
+ * This method is a declarative alternative to {@link #average(double[])}.
+ * Instead of throwing on empty input, it returns an empty {@link OptionalDouble},
+ * following the convention of the Stream API.
+ *
+ * @param numbers an array of {@code double} values, may be {@code null} or empty
+ * @return an {@link OptionalDouble} with the mean, or empty if input is null/empty
+ */
+ public static OptionalDouble averageStream(double[] numbers) {
+ if (numbers == null || numbers.length == 0) {
+ return OptionalDouble.empty();
+ }
+ return Arrays.stream(numbers).average();
+ }
}
diff --git a/src/main/java/com/thealgorithms/maths/BellNumbers.java b/src/main/java/com/thealgorithms/maths/BellNumbers.java
new file mode 100644
index 000000000000..d4dc1014f48b
--- /dev/null
+++ b/src/main/java/com/thealgorithms/maths/BellNumbers.java
@@ -0,0 +1,59 @@
+package com.thealgorithms.maths;
+
+/**
+ * The Bell numbers count the number of partitions of a set.
+ * The n-th Bell number is the number of ways a set of n elements can be partitioned
+ * into nonempty subsets.
+ *
+ *
+ * This implementation uses the Bell Triangle (Aitken's array) method.
+ * Time Complexity: O(n^2)
+ * Space Complexity: O(n^2)
+ * This class provides a method to calculate the Euclidean distance between two points in a
+ * two-dimensional plane.
+ *
+ * Formula: d = sqrt((x2 - x1)^2 + (y2 - y1)^2)
+ *
+ * Reference: https://en.wikipedia.org/wiki/Euclidean_distance
+ */
+public final class DistanceBetweenTwoPoints {
+
+ private DistanceBetweenTwoPoints() {
+ // Utility class; prevent instantiation
+ }
+
+ /**
+ * Calculate the Euclidean distance between two points.
+ *
+ * @param x1 x-coordinate of the first point
+ * @param y1 y-coordinate of the first point
+ * @param x2 x-coordinate of the second point
+ * @param y2 y-coordinate of the second point
+ * @return Euclidean distance between the two points
+ */
+ public static double calculate(final double x1, final double y1, final double x2, final double y2) {
+ final double deltaX = x2 - x1;
+ final double deltaY = y2 - y1;
+ return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+ }
+}
diff --git a/src/main/java/com/thealgorithms/maths/EvilNumber.java b/src/main/java/com/thealgorithms/maths/EvilNumber.java
new file mode 100644
index 000000000000..419133702fd4
--- /dev/null
+++ b/src/main/java/com/thealgorithms/maths/EvilNumber.java
@@ -0,0 +1,39 @@
+package com.thealgorithms.maths;
+
+/**
+ * In number theory, an evil number is a non-negative integer that has an even number of 1s in its binary expansion.
+ * Non-negative integers that are not evil are called odious numbers.
+ *
+ * Evil Number Wiki: https://en.wikipedia.org/wiki/Evil_number
+ * Odious Number Wiki: https://en.wikipedia.org/wiki/Odious_number
+ */
+public final class EvilNumber {
+
+ private EvilNumber() {
+ }
+
+ // Function to count number of one bits in a number using bitwise operators
+ private static int countOneBits(int number) {
+ int oneBitCounter = 0;
+ while (number > 0) {
+ oneBitCounter += number & 1; // increment count if last bit is 1
+ number >>= 1; // right shift to next bit
+ }
+ return oneBitCounter;
+ }
+
+ /**
+ * Check either {@code number} is an Evil number or Odious number
+ *
+ * @param number the number
+ * @return {@code true} if {@code number} is an Evil number, otherwise false (in case of of Odious number)
+ */
+ public static boolean isEvilNumber(int number) {
+ if (number < 0) {
+ throw new IllegalArgumentException("Negative numbers are not allowed.");
+ }
+
+ int noOfOneBits = countOneBits(number);
+ return noOfOneBits % 2 == 0;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/maths/ExtendedEuclideanAlgorithm.java b/src/main/java/com/thealgorithms/maths/ExtendedEuclideanAlgorithm.java
new file mode 100644
index 000000000000..4934d4493bf2
--- /dev/null
+++ b/src/main/java/com/thealgorithms/maths/ExtendedEuclideanAlgorithm.java
@@ -0,0 +1,48 @@
+package com.thealgorithms.maths;
+
+/**
+ * In mathematics, the extended Euclidean algorithm is an extension to the
+ * Euclidean algorithm, and computes, in addition to the greatest common divisor
+ * (gcd) of integers a and b, also the coefficients of BΓ©zout's identity, which
+ * are integers x and y such that ax + by = gcd(a, b).
+ *
+ *
+ * For more details, see
+ * https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
+ */
+public final class ExtendedEuclideanAlgorithm {
+
+ private ExtendedEuclideanAlgorithm() {
+ }
+
+ /**
+ * This method implements the extended Euclidean algorithm.
+ *
+ * @param a The first number.
+ * @param b The second number.
+ * @return An array of three integers:
+ *
+ * The quadratic mean is calculated as: β[(xβ^2 Γ xβ^2 Γ ... Γ xβ^2)/n]
+ *
+ * Example: For numbers [1, 7], the quadratic mean is β[(1^2+7^2)/2] = β25 = 5.0
+ *
+ * The Difference Array is an auxiliary data structure that enables efficient range update operations.
+ * It is based on the mathematical concept of Finite Differences.
+ *
+ * Key Operations:
+ *
+ * This method uses a branchless approach by allocating an extra element at the end
+ * of the array, avoiding the conditional check for the right boundary.
+ * Prefix Sum is a technique used to preprocess an array such that
+ * range sum queries can be answered in O(1) time.
+ * The preprocessing step takes O(N) time.
+ *
+ * This implementation uses a long array for the prefix sums to prevent
+ * integer overflow when the sum of elements exceeds Integer.MAX_VALUE.
+ *
+ * @see Prefix Sum (Wikipedia)
+ * @author Chahat Sandhu, singhc7
+ */
+public class PrefixSum {
+
+ private final long[] prefixSums;
+
+ /**
+ * Constructor to preprocess the input array.
+ *
+ * @param array The input integer array.
+ * @throws IllegalArgumentException if the array is null.
+ */
+ public PrefixSum(int[] array) {
+ if (array == null) {
+ throw new IllegalArgumentException("Input array cannot be null");
+ }
+ this.prefixSums = new long[array.length + 1];
+ this.prefixSums[0] = 0;
+
+ for (int i = 0; i < array.length; i++) {
+ // Automatically promotes int to long during addition
+ this.prefixSums[i + 1] = this.prefixSums[i] + array[i];
+ }
+ }
+
+ /**
+ * Calculates the sum of elements in the range [left, right].
+ * Indices are 0-based.
+ *
+ * @param left The starting index (inclusive).
+ * @param right The ending index (inclusive).
+ * @return The sum of elements from index left to right as a long.
+ * @throws IndexOutOfBoundsException if indices are out of valid range.
+ */
+ public long sumRange(int left, int right) {
+ if (left < 0 || right >= prefixSums.length - 1 || left > right) {
+ throw new IndexOutOfBoundsException("Invalid range indices");
+ }
+ return prefixSums[right + 1] - prefixSums[left];
+ }
+}
diff --git a/src/main/java/com/thealgorithms/prefixsum/PrefixSum2D.java b/src/main/java/com/thealgorithms/prefixsum/PrefixSum2D.java
new file mode 100644
index 000000000000..9c168bc6bcc4
--- /dev/null
+++ b/src/main/java/com/thealgorithms/prefixsum/PrefixSum2D.java
@@ -0,0 +1,64 @@
+package com.thealgorithms.prefixsum;
+
+/**
+ * A class that implements the 2D Prefix Sum algorithm.
+ *
+ * 2D Prefix Sum is a technique used to preprocess a 2D matrix such that
+ * sub-matrix sum queries can be answered in O(1) time.
+ * The preprocessing step takes O(N*M) time.
+ *
+ * This implementation uses a long array for the prefix sums to prevent
+ * integer overflow.
+ *
+ * @see Summed-area table (Wikipedia)
+ * @author Chahat Sandhu, singhc7
+ */
+public class PrefixSum2D {
+
+ private final long[][] prefixSums;
+
+ /**
+ * Constructor to preprocess the input matrix.
+ *
+ * @param matrix The input integer matrix.
+ * @throws IllegalArgumentException if the matrix is null or empty.
+ */
+ public PrefixSum2D(int[][] matrix) {
+ if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
+ throw new IllegalArgumentException("Input matrix cannot be null or empty");
+ }
+
+ int rows = matrix.length;
+ int cols = matrix[0].length;
+ this.prefixSums = new long[rows + 1][cols + 1];
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ // P[i+1][j+1] = current + above + left - diagonal_overlap
+ this.prefixSums[i + 1][j + 1] = matrix[i][j] + this.prefixSums[i][j + 1] + this.prefixSums[i + 1][j] - this.prefixSums[i][j];
+ }
+ }
+ }
+
+ /**
+ * Calculates the sum of the sub-matrix defined by (row1, col1) to (row2, col2).
+ * Indices are 0-based.
+ *
+ * @param row1 Top row index.
+ * @param col1 Left column index.
+ * @param row2 Bottom row index.
+ * @param col2 Right column index.
+ * @return The sum of the sub-matrix.
+ * @throws IndexOutOfBoundsException if indices are invalid.
+ */
+ public long sumRegion(int row1, int col1, int row2, int col2) {
+ if (row1 < 0 || row2 >= prefixSums.length - 1 || row2 < row1) {
+ throw new IndexOutOfBoundsException("Invalid row indices");
+ }
+ if (col1 < 0 || col2 >= prefixSums[0].length - 1 || col2 < col1) {
+ throw new IndexOutOfBoundsException("Invalid column indices");
+ }
+
+ return prefixSums[row2 + 1][col2 + 1] - prefixSums[row1][col2 + 1] - prefixSums[row2 + 1][col1] + prefixSums[row1][col1];
+ }
+}
diff --git a/src/main/java/com/thealgorithms/prefixsum/RangeSumQuery.java b/src/main/java/com/thealgorithms/prefixsum/RangeSumQuery.java
new file mode 100644
index 000000000000..14a02a2de4d0
--- /dev/null
+++ b/src/main/java/com/thealgorithms/prefixsum/RangeSumQuery.java
@@ -0,0 +1,73 @@
+package com.thealgorithms.prefixsum;
+
+/**
+ * Implements an algorithm to efficiently compute the sum of elements
+ * between any two indices in an integer array using the Prefix Sum technique.
+ *
+ *
+ * Given an array nums, this algorithm precomputes the prefix sum array
+ * to allow O(1) sum queries for any range [left, right].
+ *
+ * Let prefixSum[i] be the sum of elements from index 0 to i-1.
+ * The sum of elements from left to right is:
+ *
+ *
+ * Time Complexity: O(N) for preprocessing, O(1) per query
+ * This algorithm uses the Prefix Sum technique combined with a HashMap
+ * to achieve O(N) time complexity.
+ *
+ * Let prefixSum[i] be the sum of elements from index 0 to i.
+ * A subarray (j + 1) to i has sum k if:
+ *
+ *
+ * The HashMap stores the frequency of each prefix sum encountered so far.
+ *
+ * Time Complexity: O(N)
+ * The puzzle rules are:
* 1. Only one disc can be moved at a time.
* 2. A disc can only be placed on top of a larger disc.
* 3. All discs must start on one pole and end on another.
+ *
+ * The recursion follows three steps:
+ * 1. Move {@code n-1} discs from start to intermediate.
+ * 2. Move the largest disc from start to end.
+ * 3. Move {@code n-1} discs from intermediate to end.
+ *
- * For more information about the Tower of Hanoi, see
- * Tower of Hanoi on Wikipedia.
+ * Time Complexity: O(2^n) - exponential due to recursive expansion.
+ * Space Complexity: O(n) - recursion stack depth.
*
+ * See Tower of Hanoi on Wikipedia.
+ *
* This method is called recursively to move n-1 discs
@@ -51,15 +57,20 @@ private TowerOfHanoi() {
*
+ * Example:
+ * 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ...
+ *
- * Worst-case performance O(log n) Best-case performance O(1) Average
- * performance O(log n) Worst-case space complexity O(1)
+ * Binary search is one of the most efficient searching algorithms for finding a target element
+ * in a SORTED array. It works by repeatedly dividing the search space in half, eliminating half of
+ * the remaining elements in each step.
+ *
+ * IMPORTANT: This algorithm ONLY works correctly if the input array is sorted in ascending
+ * order.
+ *
+ * Algorithm Overview: 1. Start with the entire array (left = 0, right = array.length - 1) 2.
+ * Calculate the middle index 3. Compare the middle element with the target: - If middle element
+ * equals target: Found! Return the index - If middle element is less than target: Search the right
+ * half - If middle element is greater than target: Search the left half 4. Repeat until element is
+ * found or search space is exhausted
+ *
+ * Performance Analysis: - Best-case time complexity: O(1) - Element found at middle on first
+ * try - Average-case time complexity: O(log n) - Most common scenario - Worst-case time
+ * complexity: O(log n) - Element not found or at extreme end - Space complexity: O(1) - Only uses
+ * a constant amount of extra space
+ *
+ * Example Walkthrough: Array: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] Target: 7
+ *
+ * Step 1: left=0, right=9, mid=4, array[4]=9 (9 > 7, search left half) Step 2: left=0,
+ * right=3, mid=1, array[1]=3 (3 < 7, search right half) Step 3: left=2, right=3, mid=2,
+ * array[2]=5 (5 < 7, search right half) Step 4: left=3, right=3, mid=3, array[3]=7 (Found!
+ * Return index 3)
*
* @author Varun Upadhyay (https://github.com/varunu28)
* @author Podshivalov Nikita (https://github.com/nikitap492)
@@ -18,38 +38,96 @@
class BinarySearch implements SearchAlgorithm {
/**
- * @param array is an array where the element should be found
- * @param key is an element which should be found
- * @param Example Usage:
+ * How it works:
+ * Time Complexity: O(log n) because we halve the search space each time.
+ * Space Complexity: O(log n) due to recursive call stack.
*
- * @param array The array to make the binary search
- * @param key The number you are looking for
- * @param left The lower bound
- * @param right The upper bound
- * @return the location of the key
+ * @param
- * Worst-case performance O(log n) Best-case performance O(1) Average
- * performance O(log n) Worst-case space complexity O(1)
+ * Iterative binary search avoids recursion overhead and uses constant space.
*
- * @author Gabriele La Greca : https://github.com/thegabriele97
- * @author Podshivalov Nikita (https://github.com/nikitap492)
+ * Performance:
+ *
- * The Jump Search algorithm is particularly effective for large sorted arrays where the cost of
- * performing a linear search on the entire array would be prohibitive.
+ * How it works:
+ *
- * Worst-case performance: O(βN)
+ * Time Complexity:
+ * Space Complexity: O(1) - only uses a constant amount of extra space
+ *
+ *
+ * Edge Cases:
+ *
+ * Note: Jump Search requires a sorted array. For unsorted arrays, use Linear Search.
+ * Compared to Linear Search (O(n)), Jump Search is faster for large arrays.
+ * Compared to Binary Search (O(log n)), Jump Search is less efficient but may be
+ * preferable when jumping through a linked list or when backward scanning is costly.
*
*
* This class implements the {@link SearchAlgorithm} interface, providing a generic search method
* for any comparable type.
+ *
+ * @see SearchAlgorithm
+ * @see BinarySearch
+ * @see LinearSearch
*/
public class JumpSearch implements SearchAlgorithm {
/**
* Jump Search algorithm implementation.
*
- * @param array the sorted array containing elements
- * @param key the element to be searched
+ * @param array the sorted array containing elements (must be sorted in ascending order)
+ * @param key the element to be searched for
* @return the index of {@code key} if found, otherwise -1
*/
@Override
diff --git a/src/main/java/com/thealgorithms/searches/LinearSearch.java b/src/main/java/com/thealgorithms/searches/LinearSearch.java
index c7b70edb5112..3f273e167f0a 100644
--- a/src/main/java/com/thealgorithms/searches/LinearSearch.java
+++ b/src/main/java/com/thealgorithms/searches/LinearSearch.java
@@ -1,18 +1,36 @@
+/**
+ * Performs Linear Search on an array.
+ *
+ * Linear search checks each element one by one until the target is found
+ * or the array ends.
+ *
+ * Example:
+ * Input: [2, 4, 6, 8], target = 6
+ * Output: Index = 2
+ *
+ * Time Complexity: O(n)
+ * Space Complexity: O(1)
+ */
package com.thealgorithms.searches;
import com.thealgorithms.devutils.searches.SearchAlgorithm;
/**
- * Linear search is the easiest search algorithm It works with sorted and
- * unsorted arrays (an binary search works only with sorted array) This
- * algorithm just compares all elements of an array to find a value
+ * Linear Search is a simple searching algorithm that checks
+ * each element of the array sequentially until the target
+ * value is found or the array ends.
+ *
+ * It works for both sorted and unsorted arrays.
*
- *
- * Worst-case performance O(n) Best-case performance O(1) Average performance
- * O(n) Worst-case space complexity
+ * Time Complexity:
+ * - Best case: O(1)
+ * - Average case: O(n)
+ * - Worst case: O(n)
*
- * @author Varun Upadhyay (https://github.com/varunu28)
- * @author Podshivalov Nikita (https://github.com/nikitap492)
+ * Space Complexity: O(1)
+ *
+ * @author Varun Upadhyay
+ * @author Podshivalov Nikita
* @see BinarySearch
* @see SearchAlgorithm
*/
@@ -23,15 +41,22 @@ public class LinearSearch implements SearchAlgorithm {
*
* @param array List to be searched
* @param value Key being searched for
- * @return Location of the key
+ * @return Location of the key, -1 if array is null or empty, or key not found
*/
@Override
public
- * Worst-case performance O(log n) Best-case performance O(1) Average
- * performance O(log n) Worst-case space complexity O(1)
- *
- * @author D Sunil (https://github.com/sunilnitdgp)
- * @see SearchAlgorithm
- */
-
-public class PerfectBinarySearch
+ * Example:
+ * {@code [8, 9, 10, 1, 2, 3, 4, 5, 6, 7]}
+ *
+ *
+ * This is a modified binary search. When the array contains no duplicates, the
+ * time complexity is {@code O(log n)}. With duplicates, the algorithm still
+ * works but may degrade to {@code O(n)} in the worst case.
+ *
+ * @see Search in rotated sorted array
+ * @see SearchAlgorithm
+ */
+public final class RotatedBinarySearch implements SearchAlgorithm {
+
+ @Override
+ public The algorithm selects a pivot element and partitions the array into two
+ * subarrays such that:
+ * The subarrays are then recursively sorted until the entire array is ordered.
+ *
+ * This implementation uses randomization to reduce the probability of
+ * encountering worst-case performance on already sorted inputs.
+ *
+ * Time Complexity:
+ * Space Complexity: O(log n) due to recursion stack (in-place sorting).
+ *
+ * @author Varun Upadhyay
+ * @author Podshivalov Nikita
* @see SortAlgorithm
*/
+
class QuickSort implements SortAlgorithm {
- /**
- * This method implements the Generic Quick Sort
- *
- * @param array The array to be sorted Sorts the array in increasing order
- */
@Override
public It can be viewed as a variant of heapsort that maintains a forest of heap-ordered Leonardo trees
+ * (trees whose sizes are Leonardo numbers). The algorithm is adaptive: when the input is already
+ * sorted or nearly sorted, the heap invariants are often satisfied and the expensive rebalancing
+ * operations do little work, yielding near-linear behavior.
+ *
+ * Time Complexity:
+ * Space Complexity: O(1) auxiliary space (in-place).
+ *
+ * @see Smoothsort
+ * @see Leonardo numbers
+ * @see SortAlgorithm
+ */
+public class SmoothSort implements SortAlgorithm {
+
+ /**
+ * Leonardo numbers (L(0) = L(1) = 1, L(k+2) = L(k+1) + L(k) + 1) up to the largest value that
+ * fits into a signed 32-bit integer.
+ */
+ private static final int[] LEONARDO = {1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, 465, 753, 1219, 1973, 3193, 5167, 8361, 13529, 21891, 35421, 57313, 92735, 150049, 242785, 392835, 635621, 1028457, 1664079, 2692537, 4356617, 7049155, 11405773, 18454929, 29860703, 48315633, 78176337,
+ 126491971, 204668309, 331160281, 535828591, 866988873, 1402817465};
+
+ /**
+ * Sorts the given array in ascending order using Smooth Sort.
+ *
+ * @param array the array to sort
+ * @param The span of a price on a given day is the number of consecutive days ending on that day
+ * for which the price was less than or equal to the current day's price.
+ *
+ * Idea: keep a stack of indices whose prices are strictly greater than the current price.
+ * While processing each day, pop smaller or equal prices because they are part of the current
+ * span. After popping, the nearest greater price left on the stack tells us where the span stops.
+ *
+ * Time complexity is O(n) because each index is pushed onto the stack once and popped at most
+ * once, so the total number of stack operations grows linearly with the number of prices. This
+ * makes the stack approach efficient because it avoids rechecking earlier days repeatedly, unlike
+ * a naive nested-loop solution that can take O(n^2) time.
+ *
+ * Example: for prices [100, 80, 60, 70, 60, 75, 85], the spans are
+ * [1, 1, 1, 2, 1, 4, 6].
+ */
+public final class StockSpanProblem {
+ private StockSpanProblem() {
+ }
+
+ /**
+ * Calculates the stock span for each price in the input array.
+ *
+ * @param prices the stock prices
+ * @return the span for each day
+ * @throws IllegalArgumentException if the input array is null
+ */
+ public static int[] calculateSpan(int[] prices) {
+ if (prices == null) {
+ throw new IllegalArgumentException("Input prices cannot be null");
+ }
+
+ int[] spans = new int[prices.length];
+ Stack
+ * This does NOT implement language-aware alphabetical ordering (collation rules).
+ * It simply compares lowercase Unicode character values.
*
- * Alphabetical order is a system whereby character strings are placed in order
- * based on the position of the characters in the conventional ordering of an
- * alphabet.
+ * Non-letter characters are not allowed and will cause the check to fail.
*
- * Reference: Wikipedia: Alphabetical Order
+ * Reference:
+ * Wikipedia: Alphabetical order
*/
public final class Alphabetical {
+
private Alphabetical() {
}
/**
- * Checks whether the characters in the given string are in alphabetical order.
- * Non-letter characters will cause the check to fail.
+ * Checks whether the characters in the given string are in non-decreasing
+ * lexicographical order (case-insensitive).
+ *
+ * Rules:
+ *
+ * The LCP array stores the lengths of the longest common prefixes between
+ * lexicographically adjacent suffixes of a string. Kasai's algorithm computes
+ * this array in O(N) time given the string and its suffix array.
+ * A "word" is defined as a maximal substring consisting of non-space
+ * characters only. Trailing spaces at the end of the string are ignored.
+ *
+ * Example:
+ * This implementation runs in O(n) time complexity, where n is the length
+ * of the input string, and uses O(1) additional space.
+ */
+public class LengthOfLastWord {
+
+ /**
+ * Returns the length of the last word in the specified string.
+ *
+ * The method iterates from the end of the string, skipping trailing
+ * spaces first, and then counts the number of consecutive non-space characters
+ * characters until another space (or the beginning of the string) is reached.
+ *
+ * @param s the input string to analyze
+ * @return the length of the last word in {@code s}; returns 0 if there is no word
+ * @throws NullPointerException if {@code s} is {@code null}
+ */
+ public int lengthOfLastWord(String s) {
+ int sizeOfString = s.length() - 1;
+ int lastWordLength = 0;
+
+ // Skip trailing spaces from the end of the string
+ while (sizeOfString >= 0 && s.charAt(sizeOfString) == ' ') {
+ sizeOfString--;
+ }
+
+ // Count the characters of the last word
+ while (sizeOfString >= 0 && s.charAt(sizeOfString) != ' ') {
+ lastWordLength++;
+ sizeOfString--;
+ }
+
+ return lastWordLength;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/strings/LongestNonRepetitiveSubstring.java b/src/main/java/com/thealgorithms/strings/LongestNonRepetitiveSubstring.java
index 6808cd50602f..51e8dc6b02c3 100644
--- a/src/main/java/com/thealgorithms/strings/LongestNonRepetitiveSubstring.java
+++ b/src/main/java/com/thealgorithms/strings/LongestNonRepetitiveSubstring.java
@@ -13,6 +13,12 @@ private LongestNonRepetitiveSubstring() {
/**
* Finds the length of the longest substring without repeating characters.
*
+ * Uses the sliding window technique with a HashMap to track
+ * the last seen index of each character.
+ *
+ * Time Complexity: O(n), where n is the length of the input string.
+ * Space Complexity: O(min(n, m)), where m is the size of the character set.
+ *
* @param s the input string
* @return the length of the longest non-repetitive substring
*/
diff --git a/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java b/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java
deleted file mode 100644
index ca500357ba77..000000000000
--- a/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.thealgorithms.strings;
-
-final class LongestPalindromicSubstring {
- private LongestPalindromicSubstring() {
- }
-
- /**
- * Finds the longest palindromic substring in the given string.
- *
- * @param s the input string
- * @return the longest palindromic substring
- */
- public static String longestPalindrome(String s) {
- if (s == null || s.isEmpty()) {
- return "";
- }
- String maxStr = "";
- for (int i = 0; i < s.length(); ++i) {
- for (int j = i; j < s.length(); ++j) {
- if (isValid(s, i, j) && (j - i + 1 > maxStr.length())) {
- maxStr = s.substring(i, j + 1);
- }
- }
- }
- return maxStr;
- }
-
- private static boolean isValid(String s, int lo, int hi) {
- int n = hi - lo + 1;
- for (int i = 0; i < n / 2; ++i) {
- if (s.charAt(lo + i) != s.charAt(hi - i)) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/src/main/java/com/thealgorithms/strings/LongestRepeatedSubstring.java b/src/main/java/com/thealgorithms/strings/LongestRepeatedSubstring.java
new file mode 100644
index 000000000000..87c9278fd4bf
--- /dev/null
+++ b/src/main/java/com/thealgorithms/strings/LongestRepeatedSubstring.java
@@ -0,0 +1,83 @@
+package com.thealgorithms.strings;
+
+/**
+ * Finds the longest substring that occurs at least twice in a given string.
+ *
+ * Uses the suffix array (via {@link SuffixArray}) and Kasai's algorithm
+ * to build the LCP (Longest Common Prefix) array, then returns the substring
+ * corresponding to the maximum LCP value. Time complexity: O(n logΒ² n) for suffix array construction + O(n) for LCP. LCP[i] is the length of the longest common prefix between the suffixes
+ * at positions suffixArray[i] and suffixArray[i+1] in sorted order. Words are ranked by frequency in descending order. For equal frequencies,
+ * words are ranked in lexicographical ascending order.
+ *
+ * Reference:
+ * https://en.wikipedia.org/wiki/Top-k_problem
+ *
+ */
+public final class TopKFrequentWords {
+ private TopKFrequentWords() {
+ }
+
+ /**
+ * Finds the k most frequent words.
+ *
+ * @param words input array of words
+ * @param k number of words to return
+ * @return list of top-k words ordered by frequency then lexicographical order
+ * @throws IllegalArgumentException if words is null, k is negative, or words contains null
+ */
+ public static List
- * A string is considered valid if:
- * Tests cover a wide range of graph configurations including simple graphs,
+ * cycles, trees, disconnected components, multigraph-like structures, and
+ * various edge cases to ensure correct bridge detection.
+ *
+ *
+ * IMPORTANT contracts
+ *
+ *
+ *
+ *
+ *
+ * If you prefer value-based semantics, replace with HashMap
+ *
+ */
+public final class MiddleOfLinkedList {
+
+ private MiddleOfLinkedList() {
+ }
+
+ /**
+ * Returns the middle node of the list.
+ *
+ * @param head the head of the singly linked list; may be {@code null}
+ * @return the middle node (second middle for even-sized lists), or {@code null} if {@code head} is {@code null}
+ */
+ public static SinglyLinkedListNode middleNode(final SinglyLinkedListNode head) {
+ if (head == null) {
+ return null;
+ }
+
+ SinglyLinkedListNode slow = head;
+ SinglyLinkedListNode fast = head;
+
+ while (fast != null && fast.next != null) {
+ slow = slow.next;
+ fast = fast.next.next;
+ }
+
+ return slow;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/datastructures/queues/ReverseQueueRecursion.java b/src/main/java/com/thealgorithms/datastructures/queues/ReverseQueueRecursion.java
new file mode 100644
index 000000000000..79275dcefe20
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/queues/ReverseQueueRecursion.java
@@ -0,0 +1,28 @@
+package com.thealgorithms.datastructures.queues;
+
+import java.util.Queue;
+
+/**
+ * Reverse a queue using recursion.
+ */
+public final class ReverseQueueRecursion {
+ private ReverseQueueRecursion() {
+ // private constructor to prevent instantiation
+ }
+
+ /**
+ * Reverses the given queue recursively.
+ *
+ * @param queue the queue to reverse
+ * @param Rules:
+ *
+ *
+ *
+ * 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/SegmentTree2D.java b/src/main/java/com/thealgorithms/datastructures/trees/SegmentTree2D.java
new file mode 100644
index 000000000000..40b9e8a73533
--- /dev/null
+++ b/src/main/java/com/thealgorithms/datastructures/trees/SegmentTree2D.java
@@ -0,0 +1,201 @@
+package com.thealgorithms.datastructures.trees;
+
+/**
+ * 2D Segment Tree (Tree of Trees) implementation.
+ * This data structure supports point updates and submatrix sum queries
+ * in a 2D grid. It achieves this by nesting 1D Segment Trees within a 1D Segment Tree.
+ *
+ * Time Complexity:
+ * - Build/Initialization: O(N * M)
+ * - Point Update: O(log N * log M)
+ * - Submatrix Query: O(log N * log M)
+ *
+ * @see 2D Segment Tree
+ */
+public class SegmentTree2D {
+
+ /**
+ * Represents a 1D Segment Tree.
+ * This is equivalent to your 'Sagara' struct. It manages the columns (X-axis).
+ */
+ public static class SegmentTree1D {
+ private int n;
+ private final int[] tree;
+
+ /**
+ * Initializes the 1D Segment Tree with the nearest power of 2.
+ *
+ * @param size The expected number of elements (columns).
+ */
+ public SegmentTree1D(int size) {
+ n = 1;
+ while (n < size) {
+ n *= 2;
+ }
+ tree = new int[n * 2];
+ }
+
+ /**
+ * Recursively updates a point in the 1D tree.
+ */
+ private void update(int index, int val, int node, int lx, int rx) {
+ if (rx - lx == 1) {
+ tree[node] = val;
+ return;
+ }
+
+ int mid = lx + (rx - lx) / 2;
+ int leftChild = node * 2 + 1;
+ int rightChild = node * 2 + 2;
+
+ if (index < mid) {
+ update(index, val, leftChild, lx, mid);
+ } else {
+ update(index, val, rightChild, mid, rx);
+ }
+
+ tree[node] = tree[leftChild] + tree[rightChild];
+ }
+
+ /**
+ * Public wrapper to update a specific index.
+ *
+ * @param index The column index to update.
+ * @param val The new value.
+ */
+ public void update(int index, int val) {
+ update(index, val, 0, 0, n);
+ }
+
+ /**
+ * Retrieves the exact value at a specific leaf node.
+ *
+ * @param index The column index.
+ * @return The value at the given index.
+ */
+ public int get(int index) {
+ return query(index, index + 1, 0, 0, n);
+ }
+
+ /**
+ * Recursively queries the sum in a 1D range.
+ */
+ private int query(int l, int r, int node, int lx, int rx) {
+ if (lx >= r || rx <= l) {
+ return 0; // Out of bounds
+ }
+ if (lx >= l && rx <= r) {
+ return tree[node]; // Fully inside
+ }
+
+ int mid = lx + (rx - lx) / 2;
+ int leftSum = query(l, r, node * 2 + 1, lx, mid);
+ int rightSum = query(l, r, node * 2 + 2, mid, rx);
+
+ return leftSum + rightSum;
+ }
+
+ /**
+ * Public wrapper to query the sum in the range [l, r).
+ *
+ * @param l Left boundary (inclusive).
+ * @param r Right boundary (exclusive).
+ * @return The sum of the range.
+ */
+ public int query(int l, int r) {
+ return query(l, r, 0, 0, n);
+ }
+ }
+
+ // --- Start of 2D Segment Tree (equivalent to 'Sagara2D') ---
+
+ private int n;
+ private final SegmentTree1D[] tree;
+
+ /**
+ * Initializes the 2D Segment Tree.
+ *
+ * @param rows The number of rows in the matrix.
+ * @param cols The number of columns in the matrix.
+ */
+ public SegmentTree2D(int rows, int cols) {
+ n = 1;
+ while (n < rows) {
+ n *= 2;
+ }
+ tree = new SegmentTree1D[n * 2];
+ for (int i = 0; i < n * 2; i++) {
+ // Every node in the outer tree is a full 1D tree!
+ tree[i] = new SegmentTree1D(cols);
+ }
+ }
+
+ /**
+ * Recursively updates a point in the 2D grid.
+ */
+ private void update(int row, int col, int val, int node, int lx, int rx) {
+ if (rx - lx == 1) {
+ tree[node].update(col, val);
+ return;
+ }
+
+ int mid = lx + (rx - lx) / 2;
+ int leftChild = node * 2 + 1;
+ int rightChild = node * 2 + 2;
+
+ if (row < mid) {
+ update(row, col, val, leftChild, lx, mid);
+ } else {
+ update(row, col, val, rightChild, mid, rx);
+ }
+
+ // The value of the current node's column is the sum of its children's column values
+ int leftVal = tree[leftChild].get(col);
+ int rightVal = tree[rightChild].get(col);
+ tree[node].update(col, leftVal + rightVal);
+ }
+
+ /**
+ * Public wrapper to update a specific point (row, col).
+ *
+ * @param row The row index.
+ * @param col The column index.
+ * @param val The new value.
+ */
+ public void update(int row, int col, int val) {
+ update(row, col, val, 0, 0, n);
+ }
+
+ /**
+ * Recursively queries the sum in a submatrix.
+ */
+ private int query(int top, int bottom, int left, int right, int node, int lx, int rx) {
+ if (lx >= bottom || rx <= top) {
+ return 0; // Out of bounds
+ }
+ if (lx >= top && rx <= bottom) {
+ // Fully inside the row range, so delegate the column query to the 1D tree
+ return tree[node].query(left, right);
+ }
+
+ int mid = lx + (rx - lx) / 2;
+ int leftSum = query(top, bottom, left, right, node * 2 + 1, lx, mid);
+ int rightSum = query(top, bottom, left, right, node * 2 + 2, mid, rx);
+
+ return leftSum + rightSum;
+ }
+
+ /**
+ * Public wrapper to query the sum of a submatrix.
+ * Note: boundaries are [top, bottom) and [left, right).
+ *
+ * @param top Top row index (inclusive).
+ * @param bottom Bottom row index (exclusive).
+ * @param left Left column index (inclusive).
+ * @param right Right column index (exclusive).
+ * @return The sum of the submatrix.
+ */
+ public int query(int top, int bottom, int left, int right) {
+ return query(top, bottom, left, right, 0, 0, n);
+ }
+}
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.
+ *
+ *
> mergeAccounts(List
> accounts) {
+ if (accounts == null || accounts.isEmpty()) {
+ return List.of();
+ }
+
+ UnionFind dsu = new UnionFind(accounts.size());
+ Map
> merged = new ArrayList<>();
+ for (Map.Entry
+ *
+ *
+ * > adjacencyList) {
+ if (vertexCount < 0) {
+ throw new IllegalArgumentException("vertexCount must be non-negative");
+ }
+ if (adjacencyList == null || adjacencyList.size() != vertexCount) {
+ throw new IllegalArgumentException("adjacencyList size must equal vertexCount");
+ }
+
+ List
> adjacencyList;
+ private final List
> adjacencyList, List
+ *
+ */
+ public static long[] extendedGCD(long a, long b) {
+ if (b == 0) {
+ // Base case: gcd(a, 0) = a. The equation is a*1 + 0*0 = a.
+ return new long[] {a, 1, 0};
+ }
+
+ // Recursive call
+ long[] result = extendedGCD(b, a % b);
+ long gcd = result[0];
+ long x1 = result[1];
+ long y1 = result[2];
+
+ // Update coefficients using the results from the recursive call
+ long x = y1;
+ long y = x1 - a / b * y1;
+
+ return new long[] {gcd, x, y};
+ }
+}
diff --git a/src/main/java/com/thealgorithms/maths/Factorial.java b/src/main/java/com/thealgorithms/maths/Factorial.java
index 511cc1f84f05..8ad219a3066c 100644
--- a/src/main/java/com/thealgorithms/maths/Factorial.java
+++ b/src/main/java/com/thealgorithms/maths/Factorial.java
@@ -1,23 +1,19 @@
package com.thealgorithms.maths;
+import java.math.BigInteger;
+
public final class Factorial {
private Factorial() {
}
- /**
- * Calculate factorial N using iteration
- *
- * @param n the number
- * @return the factorial of {@code n}
- */
- public static long factorial(int n) {
+ public static BigInteger factorial(int n) {
if (n < 0) {
throw new IllegalArgumentException("Input number cannot be negative");
}
- long factorial = 1;
- for (int i = 1; i <= n; ++i) {
- factorial *= i;
+ BigInteger result = BigInteger.ONE;
+ for (int i = 1; i <= n; i++) {
+ result = result.multiply(BigInteger.valueOf(i));
}
- return factorial;
+ return result;
}
}
diff --git a/src/main/java/com/thealgorithms/maths/LuckyNumber.java b/src/main/java/com/thealgorithms/maths/LuckyNumber.java
new file mode 100644
index 000000000000..70308e1e0edd
--- /dev/null
+++ b/src/main/java/com/thealgorithms/maths/LuckyNumber.java
@@ -0,0 +1,78 @@
+package com.thealgorithms.maths;
+
+/**
+ * In number theory, a lucky number is a natural number in a set which is generated by a certain "sieve".
+ * This sieve is similar to the sieve of Eratosthenes that generates the primes,
+ * but it eliminates numbers based on their position in the remaining set,
+ * instead of their value (or position in the initial set of natural numbers).
+ *
+ * Wiki: https://en.wikipedia.org/wiki/Lucky_number
+ */
+public final class LuckyNumber {
+
+ private LuckyNumber() {
+ }
+
+ // Common validation method
+ private static void validatePositiveNumber(int number) {
+ if (number <= 0) {
+ throw new IllegalArgumentException("Number must be positive.");
+ }
+ }
+
+ // Function to check recursively for Lucky Number
+ private static boolean isLuckyRecursiveApproach(int n, int counter) {
+ // Base case: If counter exceeds n, number is lucky
+ if (counter > n) {
+ return true;
+ }
+
+ // If number is eliminated in this step, it's not lucky
+ if (n % counter == 0) {
+ return false;
+ }
+
+ // Calculate new position after removing every counter-th number
+ int newNumber = n - (n / counter);
+
+ // Recursive call for next round
+ return isLuckyRecursiveApproach(newNumber, counter + 1);
+ }
+
+ /**
+ * Check if {@code number} is a Lucky number or not using recursive approach
+ *
+ * @param number the number
+ * @return {@code true} if {@code number} is a Lucky number, otherwise false
+ */
+ public static boolean isLuckyNumber(int number) {
+ validatePositiveNumber(number);
+ int counterStarting = 2;
+ return isLuckyRecursiveApproach(number, counterStarting);
+ }
+
+ /**
+ * Check if {@code number} is a Lucky number or not using iterative approach
+ *
+ * @param number the number
+ * @return {@code true} if {@code number} is a Lucky number, otherwise false
+ */
+ public static boolean isLucky(int number) {
+ validatePositiveNumber(number);
+
+ int counter = 2; // Position starts from 2 (since first elimination happens at 2)
+ int position = number; // The position of the number in the sequence
+
+ while (counter <= position) {
+ if (position % counter == 0) {
+ return false;
+ } // Number is eliminated
+
+ // Update the position of n after removing every counter-th number
+ position = position - (position / counter);
+ counter++;
+ }
+
+ return true; // Survives all eliminations β Lucky Number
+ }
+}
diff --git a/src/main/java/com/thealgorithms/maths/Means.java b/src/main/java/com/thealgorithms/maths/Means.java
index 5445a3caebc7..d77eb1d3f661 100644
--- a/src/main/java/com/thealgorithms/maths/Means.java
+++ b/src/main/java/com/thealgorithms/maths/Means.java
@@ -107,6 +107,28 @@ public static Double harmonic(final Iterable
+ * 1/f = 1/v + 1/u
+ *
+ *
+ * where:
+ *
+ *
+ *
+ * Uses the Cartesian sign convention.
+ *
+ * @see Thin Lens
+ */
+public final class ThinLens {
+
+ private ThinLens() {
+ throw new AssertionError("No instances.");
+ }
+
+ /**
+ * Computes the image distance using the thin lens formula.
+ *
+ * @param focalLength focal length of the lens (f)
+ * @param objectDistance object distance (u)
+ * @return image distance (v)
+ * @throws IllegalArgumentException if focal length or object distance is zero
+ */
+ public static double imageDistance(double focalLength, double objectDistance) {
+
+ if (focalLength == 0 || objectDistance == 0) {
+ throw new IllegalArgumentException("Focal length and object distance must be non-zero.");
+ }
+
+ return 1.0 / ((1.0 / focalLength) - (1.0 / objectDistance));
+ }
+
+ /**
+ * Computes magnification of the image.
+ *
+ *
+ * m = v / u
+ *
+ *
+ * @param imageDistance image distance (v)
+ * @param objectDistance object distance (u)
+ * @return magnification
+ * @throws IllegalArgumentException if object distance is zero
+ */
+ public static double magnification(double imageDistance, double objectDistance) {
+
+ if (objectDistance == 0) {
+ throw new IllegalArgumentException("Object distance must be non-zero.");
+ }
+
+ return imageDistance / objectDistance;
+ }
+
+ /**
+ * Determines whether the image formed is real or virtual.
+ *
+ * @param imageDistance image distance (v)
+ * @return {@code true} if image is real, {@code false} if virtual
+ */
+ public static boolean isRealImage(double imageDistance) {
+ return imageDistance > 0;
+ }
+}
diff --git a/src/main/java/com/thealgorithms/prefixsum/DifferenceArray.java b/src/main/java/com/thealgorithms/prefixsum/DifferenceArray.java
new file mode 100644
index 000000000000..1be55039cff0
--- /dev/null
+++ b/src/main/java/com/thealgorithms/prefixsum/DifferenceArray.java
@@ -0,0 +1,87 @@
+package com.thealgorithms.prefixsum;
+
+/**
+ * Implements the Difference Array algorithm.
+ *
+ *
+ *
+ *
+ * prefixSum[right + 1] - prefixSum[left]
+ *
+ *
+ * Space Complexity: O(N)
+ *
+ * prefixSum[i] - prefixSum[j] = k
+ *
+ *
+ * Space Complexity: O(N)
+ *
+ * Integer[] numbers = {1, 3, 5, 7, 9, 11};
+ * int result = new BinarySearch().find(numbers, 7);
+ * // result will be 3 (index of element 7)
+ *
+ * int notFound = new BinarySearch().find(numbers, 4);
+ * // notFound will be -1 (element 4 does not exist)
+ *
+ *
+ * @param
+ *
+ *
+ *
+ *
+ *
+ * @author Gabriele La Greca
+ * @author Podshivalov Nikita
* @see SearchAlgorithm
* @see BinarySearch
*/
public final class IterativeBinarySearch implements SearchAlgorithm {
/**
- * This method implements an iterative version of binary search algorithm
+ * Performs iterative binary search on a sorted array.
*
- * @param array a sorted array
- * @param key the key to search in array
- * @return the index of key in the array or -1 if not found
+ * @param array the sorted array
+ * @param key the element to search
+ * @param
+ *
*
*
- * Best-case performance: O(1)
- * Average performance: O(βN)
- * Worst-case space complexity: O(1)
+ * Example:
+ * Array: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19], Target: 9
+ * Step 1: Jump from index 0 β 3 β 6 (9 < 13, so we found the block)
+ * Step 2: Linear search from index 3 to 6: found 9 at index 4
+ * Result: Index = 4
+ *
+ *
+ * - Best-case: O(1) - element found at first position
+ * - Average: O(βn) - optimal block size reduces jumps
+ * - Worst-case: O(βn) - element at end of array or not present
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
*
- * @param s the input string
- * @return {@code true} if all characters are in alphabetical order (case-insensitive), otherwise {@code false}
+ * @param s input string
+ * @return {@code true} if characters are in non-decreasing order, otherwise {@code false}
*/
public static boolean isAlphabetical(String s) {
- s = s.toLowerCase();
- for (int i = 0; i < s.length() - 1; ++i) {
- if (!Character.isLetter(s.charAt(i)) || s.charAt(i) > s.charAt(i + 1)) {
+ if (s == null || s.isBlank()) {
+ return false;
+ }
+
+ String normalized = s.toLowerCase(Locale.ROOT);
+
+ if (!Character.isLetter(normalized.charAt(0))) {
+ return false;
+ }
+
+ for (int i = 1; i < normalized.length(); i++) {
+ char prev = normalized.charAt(i - 1);
+ char curr = normalized.charAt(i);
+
+ if (!Character.isLetter(curr) || prev > curr) {
return false;
}
}
- return !s.isEmpty() && Character.isLetter(s.charAt(s.length() - 1));
+ return true;
}
}
diff --git a/src/main/java/com/thealgorithms/strings/Anagrams.java b/src/main/java/com/thealgorithms/strings/Anagrams.java
index 5b97af0758f2..7bd84d47508f 100644
--- a/src/main/java/com/thealgorithms/strings/Anagrams.java
+++ b/src/main/java/com/thealgorithms/strings/Anagrams.java
@@ -5,7 +5,7 @@
/**
* An anagram is a word or phrase formed by rearranging the letters of a different word or phrase,
- * typically using all the original letters exactly once.[1]
+ * typically using all the original letters exactly once.
* For example, the word anagram itself can be rearranged into nag a ram,
* also the word binary into brainy and the word adobe into abode.
* Reference from https://en.wikipedia.org/wiki/Anagram
diff --git a/src/main/java/com/thealgorithms/strings/KMP.java b/src/main/java/com/thealgorithms/strings/KMP.java
index 07d3b0415006..0317abe6f39a 100644
--- a/src/main/java/com/thealgorithms/strings/KMP.java
+++ b/src/main/java/com/thealgorithms/strings/KMP.java
@@ -1,5 +1,8 @@
package com.thealgorithms.strings;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Implementation of KnuthβMorrisβPratt algorithm Usage: see the main function
* for an example
@@ -8,16 +11,19 @@ public final class KMP {
private KMP() {
}
- // a working example
-
- public static void main(String[] args) {
- final String haystack = "AAAAABAAABA"; // This is the full string
- final String needle = "AAAA"; // This is the substring that we want to find
- kmpMatcher(haystack, needle);
- }
+ /**
+ * find the starting index in string haystack[] that matches the search word P[]
+ *
+ * @param haystack The text to be searched
+ * @param needle The pattern to be searched for
+ * @return A list of starting indices where the pattern is found
+ */
+ public static List{@code
+ * LengthOfLastWord obj = new LengthOfLastWord();
+ * System.out.println(obj.lengthOfLastWord("Hello World")); // Output: 5
+ * System.out.println(obj.lengthOfLastWord(" fly me to the moon ")); // Output: 4
+ * System.out.println(obj.lengthOfLastWord("luffy is still joyboy")); // Output: 6
+ * }
+ *
+ *
- *
- *
- * Allowed characters: '(', ')', '{', '}', '[', ']'
- */
-public final class ValidParentheses {
- private ValidParentheses() {
- }
-
- private static final Map> adj = new ArrayList<>();
+ for (int i = 0; i < 3; i++) {
+ adj.add(new ArrayList<>());
+ }
+ adj.get(0).add(1);
+ adj.get(1).add(0);
+ adj.get(1).add(2);
+ adj.get(2).add(1);
+
+ CentroidDecomposition.CentroidTree tree = new CentroidDecomposition.CentroidTree(adj);
+ assertEquals(3, tree.size());
+ assertEquals(1, tree.getRoot());
+ }
+
+ @Test
+ void testNullAdjacencyList() {
+ assertThrows(IllegalArgumentException.class, () -> { new CentroidDecomposition.CentroidTree(null); });
+ }
+
+ @Test
+ void testEmptyAdjacencyList() {
+ assertThrows(IllegalArgumentException.class, () -> { new CentroidDecomposition.CentroidTree(new ArrayList<>()); });
+ }
+}
diff --git a/src/test/java/com/thealgorithms/datastructures/trees/SegmentTree2DTest.java b/src/test/java/com/thealgorithms/datastructures/trees/SegmentTree2DTest.java
new file mode 100644
index 000000000000..db081da2550a
--- /dev/null
+++ b/src/test/java/com/thealgorithms/datastructures/trees/SegmentTree2DTest.java
@@ -0,0 +1,71 @@
+package com.thealgorithms.datastructures.trees;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class SegmentTree2DTest {
+
+ @Test
+ void testInitialEmptyQueries() {
+ SegmentTree2D segmentTree = new SegmentTree2D(4, 4);
+
+ // Initial tree should return 0 for any query
+ assertEquals(0, segmentTree.query(0, 4, 0, 4));
+ assertEquals(0, segmentTree.query(1, 3, 1, 3));
+ }
+
+ @Test
+ void testUpdateAndPointQuery() {
+ SegmentTree2D segmentTree = new SegmentTree2D(5, 5);
+
+ segmentTree.update(2, 3, 10);
+ segmentTree.update(0, 0, 5);
+
+ // Querying single points [row, row+1) x [col, col+1)
+ assertEquals(10, segmentTree.query(2, 3, 3, 4));
+ assertEquals(5, segmentTree.query(0, 1, 0, 1));
+
+ // Empty point should be 0
+ assertEquals(0, segmentTree.query(1, 2, 1, 2));
+ }
+
+ @Test
+ void testSubmatrixQuery() {
+ SegmentTree2D segmentTree = new SegmentTree2D(4, 4);
+
+ // Matrix simulation:
+ // [1, 2, 0, 0]
+ // [3, 4, 0, 0]
+ // [0, 0, 0, 0]
+ // [0, 0, 0, 0]
+ segmentTree.update(0, 0, 1);
+ segmentTree.update(0, 1, 2);
+ segmentTree.update(1, 0, 3);
+ segmentTree.update(1, 1, 4);
+
+ // Top-left 2x2 sum: 1+2+3+4 = 10
+ assertEquals(10, segmentTree.query(0, 2, 0, 2));
+
+ // First row sum: 1+2 = 3
+ assertEquals(3, segmentTree.query(0, 1, 0, 4));
+
+ // Second column sum: 2+4 = 6
+ assertEquals(6, segmentTree.query(0, 4, 1, 2));
+ }
+
+ @Test
+ void testUpdateOverwriting() {
+ SegmentTree2D segmentTree = new SegmentTree2D(3, 3);
+
+ segmentTree.update(1, 1, 5);
+ assertEquals(5, segmentTree.query(1, 2, 1, 2));
+
+ // Overwrite the same point
+ segmentTree.update(1, 1, 20);
+ assertEquals(20, segmentTree.query(1, 2, 1, 2));
+
+ // Full matrix sum should just be this point
+ assertEquals(20, segmentTree.query(0, 3, 0, 3));
+ }
+}
diff --git a/src/test/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTreeTest.java b/src/test/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTreeTest.java
new file mode 100644
index 000000000000..c5973168438e
--- /dev/null
+++ b/src/test/java/com/thealgorithms/datastructures/trees/ThreadedBinaryTreeTest.java
@@ -0,0 +1,50 @@
+/*
+ * TheAlgorithms (https://github.com/TheAlgorithms/Java)
+ * Author: Shewale41
+ * This file is licensed under the MIT License.
+ */
+
+package com.thealgorithms.datastructures.trees;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Basic tests for ThreadedBinaryTree inorder traversal.
+ */
+public class ThreadedBinaryTreeTest {
+
+ @Test
+ public void testInorderTraversalSimple() {
+ ThreadedBinaryTree tree = new ThreadedBinaryTree();
+ tree.insert(50);
+ tree.insert(30);
+ tree.insert(70);
+ tree.insert(20);
+ tree.insert(40);
+ tree.insert(60);
+ tree.insert(80);
+
+ List
> accounts = List.of(List.of("abc", "abc@mail.com", "abx@mail.com"), List.of("abc", "abc@mail.com", "aby@mail.com"), List.of("Mary", "mary@mail.com"), List.of("John", "johnnybravo@mail.com"));
+
+ List
> merged = AccountMerge.mergeAccounts(accounts);
+
+ List
> expected = List.of(List.of("John", "johnnybravo@mail.com"), List.of("Mary", "mary@mail.com"), List.of("abc", "abc@mail.com", "abx@mail.com", "aby@mail.com"));
+
+ assertEquals(expected, merged);
+ }
+
+ @Test
+ void testAccountsWithSameNameButNoSharedEmailStaySeparate() {
+ List
> accounts = List.of(List.of("Alex", "alex1@mail.com"), List.of("Alex", "alex2@mail.com"));
+
+ List
> merged = AccountMerge.mergeAccounts(accounts);
+ List
> expected = List.of(List.of("Alex", "alex1@mail.com"), List.of("Alex", "alex2@mail.com"));
+
+ assertEquals(expected, merged);
+ }
+
+ @Test
+ void testEmptyInput() {
+ assertEquals(List.of(), AccountMerge.mergeAccounts(List.of()));
+ }
+
+ @Test
+ void testNullInput() {
+ assertEquals(List.of(), AccountMerge.mergeAccounts(null));
+ }
+
+ @Test
+ void testTransitiveMergeAndDuplicateEmails() {
+ List
> accounts = List.of(List.of("A", "a1@mail.com", "a2@mail.com"), List.of("A", "a2@mail.com", "a3@mail.com"), List.of("A", "a3@mail.com", "a4@mail.com", "a4@mail.com"));
+
+ List
> merged = AccountMerge.mergeAccounts(accounts);
+
+ List
> expected = List.of(List.of("A", "a1@mail.com", "a2@mail.com", "a3@mail.com", "a4@mail.com"));
+
+ assertEquals(expected, merged);
+ }
+
+ @Test
+ void testAccountsWithNoEmailsArePreserved() {
+ List
> accounts = List.of(List.of("Alex"), List.of("Alex", "alex1@mail.com"), List.of("Bob"));
+
+ List
> merged = AccountMerge.mergeAccounts(accounts);
+ List
> expected = List.of(List.of("Alex"), List.of("Alex", "alex1@mail.com"), List.of("Bob"));
+
+ assertEquals(expected, merged);
+ }
+}
diff --git a/src/test/java/com/thealgorithms/graph/GomoryHuTreeTest.java b/src/test/java/com/thealgorithms/graph/GomoryHuTreeTest.java
new file mode 100644
index 000000000000..241f23c0fa1d
--- /dev/null
+++ b/src/test/java/com/thealgorithms/graph/GomoryHuTreeTest.java
@@ -0,0 +1,132 @@
+package com.thealgorithms.graph;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Queue;
+import java.util.Random;
+import java.util.random.RandomGenerator;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+class GomoryHuTreeTest {
+
+ @Test
+ @DisplayName("Single node graph")
+ void singleNode() {
+ int[][] cap = {{0}};
+ int[][] res = GomoryHuTree.buildTree(cap);
+ int[] parent = res[0];
+ int[] weight = res[1];
+ assertEquals(-1, parent[0]);
+ assertEquals(0, weight[0]);
+ }
+
+ @Test
+ @DisplayName("Triangle undirected graph with known min-cuts")
+ void triangleGraph() {
+ // 0-1:3, 1-2:2, 0-2:4
+ int[][] cap = new int[3][3];
+ cap[0][1] = 3;
+ cap[1][0] = 3;
+ cap[1][2] = 2;
+ cap[2][1] = 2;
+ cap[0][2] = 4;
+ cap[2][0] = 4;
+
+ int[][] tree = GomoryHuTree.buildTree(cap);
+ // validate all pairs via path-min-edge equals maxflow
+ validateAllPairs(cap, tree);
+ }
+
+ @Test
+ @DisplayName("Random small undirected graphs compare to EdmondsKarp")
+ void randomSmallGraphs() {
+ Random rng = new Random(42);
+ for (int n = 2; n <= 6; n++) {
+ for (int iter = 0; iter < 10; iter++) {
+ int[][] cap = randSymmetricMatrix(n, 0, 5, rng);
+ int[][] tree = GomoryHuTree.buildTree(cap);
+ validateAllPairs(cap, tree);
+ }
+ }
+ }
+
+ private static int[][] randSymmetricMatrix(int n, int lo, int hi, RandomGenerator rng) {
+ int[][] a = new int[n][n];
+ for (int i = 0; i < n; i++) {
+ for (int j = i + 1; j < n; j++) {
+ int w = rng.nextInt(hi - lo + 1) + lo;
+ a[i][j] = w;
+ a[j][i] = w;
+ }
+ }
+ // zero diagonal
+ for (int i = 0; i < n; i++) {
+ a[i][i] = 0;
+ }
+ return a;
+ }
+
+ private static void validateAllPairs(int[][] cap, int[][] tree) {
+ int n = cap.length;
+ int[] parent = tree[0];
+ int[] weight = tree[1];
+
+ // build adjacency list of tree without generic array creation
+ List
> g = new ArrayList<>();
+ for (int i = 0; i < n; i++) {
+ g.add(new ArrayList<>());
+ }
+ for (int v = 1; v < n; v++) {
+ int u = parent[v];
+ int w = weight[v];
+ g.get(u).add(new int[] {v, w});
+ g.get(v).add(new int[] {u, w});
+ }
+
+ for (int s = 0; s < n; s++) {
+ for (int t = s + 1; t < n; t++) {
+ int treeVal = minEdgeOnPath(g, s, t);
+ int flowVal = EdmondsKarp.maxFlow(cap, s, t);
+ assertEquals(flowVal, treeVal, "pair (" + s + "," + t + ")");
+ }
+ }
+ }
+
+ private static int minEdgeOnPath(List
> g, int s, int t) {
+ // BFS to record parent and edge weight along the path, since it's a tree, unique path exists
+ int n = g.size();
+ int[] parent = new int[n];
+ int[] edgeW = new int[n];
+ Arrays.fill(parent, -1);
+ Queue
> buildGraph(int vertexCount, int[][] edges) {
+ List
> adj = new ArrayList<>();
+ for (int i = 0; i < vertexCount; i++) {
+ adj.add(new ArrayList<>());
+ }
+ for (int[] edge : edges) {
+ adj.get(edge[0]).add(edge[1]);
+ adj.get(edge[1]).add(edge[0]);
+ }
+ return adj;
+ }
+
+ /**
+ * Sorts bridges for deterministic comparison.
+ */
+ private static void sortBridges(List
> adj = buildGraph(3, new int[][] {{0, 1}, {1, 2}});
+ List
> adj = buildGraph(3, new int[][] {{0, 1}, {1, 2}, {2, 0}});
+ List
> adj = buildGraph(5, new int[][] {{0, 1}, {0, 2}, {1, 3}, {1, 4}});
+ List
> adj = buildGraph(7, new int[][] {{0, 1}, {1, 2}, {2, 3}, {3, 0}, {2, 4}, {4, 5}, {5, 6}});
+ List
> adj = buildGraph(5, new int[][] {{0, 1}, {2, 3}, {3, 4}, {4, 2}});
+ List
> adj = buildGraph(1, new int[][] {});
+ List
> adj = buildGraph(2, new int[][] {{0, 1}});
+ List