Skip to content

Commit d41d137

Browse files
Merge branch 'master' into patch-7
2 parents 3efcd17 + d2744b5 commit d41d137

File tree

13 files changed

+624
-39
lines changed

13 files changed

+624
-39
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ jobs:
2020
if: >-
2121
github.event_name == 'pull_request' &&
2222
github.event.pull_request.head.repo.full_name != github.repository
23-
uses: codecov/codecov-action@v5
23+
uses: codecov/codecov-action@v6
2424
with:
2525
fail_ci_if_error: true
2626
- name: Upload coverage to codecov (with token)
2727
if: >
2828
github.repository == 'TheAlgorithms/Java' &&
2929
(github.event_name != 'pull_request' ||
3030
github.event.pull_request.head.repo.full_name == github.repository)
31-
uses: codecov/codecov-action@v5
31+
uses: codecov/codecov-action@v6
3232
with:
3333
token: ${{ secrets.CODECOV_TOKEN }}
3434
fail_ci_if_error: true

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,14 @@
112112
<dependency>
113113
<groupId>com.puppycrawl.tools</groupId>
114114
<artifactId>checkstyle</artifactId>
115-
<version>13.3.0</version>
115+
<version>13.4.0</version>
116116
</dependency>
117117
</dependencies>
118118
</plugin>
119119
<plugin>
120120
<groupId>com.github.spotbugs</groupId>
121121
<artifactId>spotbugs-maven-plugin</artifactId>
122-
<version>4.9.8.2</version>
122+
<version>4.9.8.3</version>
123123
<configuration>
124124
<excludeFilterFile>spotbugs-exclude.xml</excludeFilterFile>
125125
<includeTests>true</includeTests>
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package com.thealgorithms.graph;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
/**
7+
* Implementation of Tarjan's Bridge-Finding Algorithm for undirected graphs.
8+
*
9+
* <p>A <b>bridge</b> (also called a cut-edge) is an edge in an undirected graph whose removal
10+
* increases the number of connected components. Bridges represent critical links
11+
* in a network — if any bridge is removed, part of the network becomes unreachable.</p>
12+
*
13+
* <p>The algorithm performs a single Depth-First Search (DFS) traversal, tracking two
14+
* values for each vertex:</p>
15+
* <ul>
16+
* <li><b>discoveryTime</b> — the time step at which the vertex was first visited.</li>
17+
* <li><b>lowLink</b> — the smallest discovery time reachable from the subtree rooted
18+
* at that vertex (via back edges).</li>
19+
* </ul>
20+
*
21+
* <p>An edge (u, v) is a bridge if and only if {@code lowLink[v] > discoveryTime[u]},
22+
* meaning there is no back edge from the subtree of v that can reach u or any ancestor of u.</p>
23+
*
24+
* <p>Time Complexity: O(V + E), where V is the number of vertices and E is the number of edges.</p>
25+
* <p>Space Complexity: O(V + E) for the adjacency list, discovery/low arrays, and recursion stack.</p>
26+
*
27+
* @see <a href="https://en.wikipedia.org/wiki/Bridge_(graph_theory)">Wikipedia: Bridge (graph theory)</a>
28+
*/
29+
public final class TarjanBridges {
30+
31+
private TarjanBridges() {
32+
throw new UnsupportedOperationException("Utility class");
33+
}
34+
35+
/**
36+
* Finds all bridge edges in an undirected graph.
37+
*
38+
* <p>The graph is represented as an adjacency list where each vertex is identified by
39+
* an integer in the range {@code [0, vertexCount)}. For each undirected edge (u, v),
40+
* v must appear in {@code adjacencyList.get(u)} and u must appear in
41+
* {@code adjacencyList.get(v)}.</p>
42+
*
43+
* @param vertexCount the total number of vertices in the graph (must be non-negative)
44+
* @param adjacencyList the adjacency list representation of the graph; must contain
45+
* exactly {@code vertexCount} entries (one per vertex)
46+
* @return a list of bridge edges, where each bridge is represented as an {@code int[]}
47+
* of length 2 with {@code edge[0] < edge[1]}; returns an empty list if no bridges exist
48+
* @throws IllegalArgumentException if {@code vertexCount} is negative, or if
49+
* {@code adjacencyList} is null or its size does not match
50+
* {@code vertexCount}
51+
*/
52+
public static List<int[]> findBridges(int vertexCount, List<List<Integer>> adjacencyList) {
53+
if (vertexCount < 0) {
54+
throw new IllegalArgumentException("vertexCount must be non-negative");
55+
}
56+
if (adjacencyList == null || adjacencyList.size() != vertexCount) {
57+
throw new IllegalArgumentException("adjacencyList size must equal vertexCount");
58+
}
59+
60+
List<int[]> bridges = new ArrayList<>();
61+
62+
if (vertexCount == 0) {
63+
return bridges;
64+
}
65+
66+
BridgeFinder finder = new BridgeFinder(vertexCount, adjacencyList, bridges);
67+
68+
// Run DFS from every unvisited vertex to handle disconnected graphs
69+
for (int i = 0; i < vertexCount; i++) {
70+
if (!finder.visited[i]) {
71+
finder.dfs(i, -1);
72+
}
73+
}
74+
75+
return bridges;
76+
}
77+
78+
private static class BridgeFinder {
79+
private final List<List<Integer>> adjacencyList;
80+
private final List<int[]> bridges;
81+
private final int[] discoveryTime;
82+
private final int[] lowLink;
83+
boolean[] visited;
84+
private int timer;
85+
86+
BridgeFinder(int vertexCount, List<List<Integer>> adjacencyList, List<int[]> bridges) {
87+
this.adjacencyList = adjacencyList;
88+
this.bridges = bridges;
89+
this.discoveryTime = new int[vertexCount];
90+
this.lowLink = new int[vertexCount];
91+
this.visited = new boolean[vertexCount];
92+
this.timer = 0;
93+
}
94+
95+
/**
96+
* Performs DFS from the given vertex, computing discovery times and low-link values,
97+
* and collects any bridge edges found.
98+
*
99+
* @param u the current vertex being explored
100+
* @param parent the parent of u in the DFS tree (-1 if u is a root)
101+
*/
102+
void dfs(int u, int parent) {
103+
visited[u] = true;
104+
discoveryTime[u] = timer;
105+
lowLink[u] = timer;
106+
timer++;
107+
108+
for (int v : adjacencyList.get(u)) {
109+
if (!visited[v]) {
110+
dfs(v, u);
111+
lowLink[u] = Math.min(lowLink[u], lowLink[v]);
112+
113+
if (lowLink[v] > discoveryTime[u]) {
114+
bridges.add(new int[] {Math.min(u, v), Math.max(u, v)});
115+
}
116+
} else if (v != parent) {
117+
lowLink[u] = Math.min(lowLink[u], discoveryTime[v]);
118+
}
119+
}
120+
}
121+
}
122+
}

src/main/java/com/thealgorithms/maths/Volume.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,16 @@ public static double volumeFrustumOfPyramid(double upperBaseArea, double lowerBa
125125
public static double volumeTorus(double majorRadius, double minorRadius) {
126126
return 2 * Math.PI * Math.PI * majorRadius * minorRadius * minorRadius;
127127
}
128+
129+
/**
130+
* Calculate the volume of an ellipsoid.
131+
*
132+
* @param a first semi-axis of an ellipsoid
133+
* @param b second semi-axis of an ellipsoid
134+
* @param c third semi-axis of an ellipsoid
135+
* @return volume of the ellipsoid
136+
*/
137+
public static double volumeEllipsoid(double a, double b, double c) {
138+
return (4 * Math.PI * a * b * c) / 3;
139+
}
128140
}

src/main/java/com/thealgorithms/searches/InterpolationSearch.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
/**
2+
* Interpolation Search estimates the position of the target value
3+
* based on the distribution of values.
4+
*
5+
* Example:
6+
* Input: [10, 20, 30, 40], target = 30
7+
* Output: Index = 2
8+
*
9+
* Time Complexity: O(log log n) (average case)
10+
* Space Complexity: O(1)
11+
*/
112
package com.thealgorithms.searches;
213

314
/**

src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,53 @@
33
import com.thealgorithms.devutils.searches.SearchAlgorithm;
44

55
/**
6-
* Binary search is one of the most popular algorithms This class represents
7-
* iterative version {@link BinarySearch} Iterative binary search is likely to
8-
* have lower constant factors because it doesn't involve the overhead of
9-
* manipulating the call stack. But in java the recursive version can be
10-
* optimized by the compiler to this version.
6+
* Binary search is one of the most popular algorithms.
7+
* This class represents the iterative version of {@link BinarySearch}.
118
*
12-
* <p>
13-
* Worst-case performance O(log n) Best-case performance O(1) Average
14-
* performance O(log n) Worst-case space complexity O(1)
9+
* <p>Iterative binary search avoids recursion overhead and uses constant space.
1510
*
16-
* @author Gabriele La Greca : https://github.com/thegabriele97
17-
* @author Podshivalov Nikita (https://github.com/nikitap492)
11+
* <p>Performance:
12+
* <ul>
13+
* <li>Best-case: O(1)</li>
14+
* <li>Average-case: O(log n)</li>
15+
* <li>Worst-case: O(log n)</li>
16+
* <li>Space complexity: O(1)</li>
17+
* </ul>
18+
*
19+
* @author Gabriele La Greca
20+
* @author Podshivalov Nikita
1821
* @see SearchAlgorithm
1922
* @see BinarySearch
2023
*/
2124
public final class IterativeBinarySearch implements SearchAlgorithm {
2225

2326
/**
24-
* This method implements an iterative version of binary search algorithm
27+
* Performs iterative binary search on a sorted array.
2528
*
26-
* @param array a sorted array
27-
* @param key the key to search in array
28-
* @return the index of key in the array or -1 if not found
29+
* @param array the sorted array
30+
* @param key the element to search
31+
* @param <T> type of elements (must be Comparable)
32+
* @return index of the key if found, otherwise -1
2933
*/
3034
@Override
3135
public <T extends Comparable<T>> int find(T[] array, T key) {
32-
int l;
33-
int r;
34-
int k;
35-
int cmp;
36+
if (array == null || array.length == 0) {
37+
return -1;
38+
}
3639

37-
l = 0;
38-
r = array.length - 1;
40+
int left = 0;
41+
int right = array.length - 1;
3942

40-
while (l <= r) {
41-
k = (l + r) >>> 1;
42-
cmp = key.compareTo(array[k]);
43+
while (left <= right) {
44+
int mid = (left + right) >>> 1;
45+
int cmp = key.compareTo(array[mid]);
4346

4447
if (cmp == 0) {
45-
return k;
48+
return mid;
4649
} else if (cmp < 0) {
47-
r = --k;
50+
right = mid - 1;
4851
} else {
49-
l = ++k;
52+
left = mid + 1;
5053
}
5154
}
5255

src/main/java/com/thealgorithms/searches/JumpSearch.java

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,50 @@
1212
* Once the range is found, a linear search is performed within that block.
1313
*
1414
* <p>
15-
* The Jump Search algorithm is particularly effective for large sorted arrays where the cost of
16-
* performing a linear search on the entire array would be prohibitive.
15+
* <b>How it works:</b>
16+
* <ol>
17+
* <li>Calculate the optimal block size as √n (square root of array length)</li>
18+
* <li>Jump ahead by the block size until the current element is greater than the target</li>
19+
* <li>Perform a linear search backwards within the identified block</li>
20+
* </ol>
1721
*
1822
* <p>
19-
* Worst-case performance: O(√N)<br>
20-
* Best-case performance: O(1)<br>
21-
* Average performance: O(√N)<br>
22-
* Worst-case space complexity: O(1)
23+
* <b>Example:</b><br>
24+
* Array: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19], Target: 9<br>
25+
* Step 1: Jump from index 0 → 3 → 6 (9 < 13, so we found the block)<br>
26+
* Step 2: Linear search from index 3 to 6: found 9 at index 4<br>
27+
* Result: Index = 4
28+
*
29+
* <p>
30+
* <b>Time Complexity:</b><br>
31+
* - Best-case: O(1) - element found at first position<br>
32+
* - Average: O(√n) - optimal block size reduces jumps<br>
33+
* - Worst-case: O(√n) - element at end of array or not present<br>
34+
*
35+
* <p>
36+
* <b>Space Complexity:</b> O(1) - only uses a constant amount of extra space
37+
*
38+
* <p>
39+
* <b>Note:</b> Jump Search requires a sorted array. For unsorted arrays, use Linear Search.
40+
* Compared to Linear Search (O(n)), Jump Search is faster for large arrays.
41+
* Compared to Binary Search (O(log n)), Jump Search is less efficient but may be
42+
* preferable when jumping through a linked list or when backward scanning is costly.
2343
*
2444
* <p>
2545
* This class implements the {@link SearchAlgorithm} interface, providing a generic search method
2646
* for any comparable type.
47+
*
48+
* @see SearchAlgorithm
49+
* @see BinarySearch
50+
* @see LinearSearch
2751
*/
2852
public class JumpSearch implements SearchAlgorithm {
2953

3054
/**
3155
* Jump Search algorithm implementation.
3256
*
33-
* @param array the sorted array containing elements
34-
* @param key the element to be searched
57+
* @param array the sorted array containing elements (must be sorted in ascending order)
58+
* @param key the element to be searched for
3559
* @return the index of {@code key} if found, otherwise -1
3660
*/
3761
@Override

src/main/java/com/thealgorithms/searches/LinearSearch.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
/**
2+
* Performs Linear Search on an array.
3+
*
4+
* Linear search checks each element one by one until the target is found
5+
* or the array ends.
6+
*
7+
* Example:
8+
* Input: [2, 4, 6, 8], target = 6
9+
* Output: Index = 2
10+
*
11+
* Time Complexity: O(n)
12+
* Space Complexity: O(1)
13+
*/
114
package com.thealgorithms.searches;
215

316
import com.thealgorithms.devutils.searches.SearchAlgorithm;
@@ -28,10 +41,13 @@ public class LinearSearch implements SearchAlgorithm {
2841
*
2942
* @param array List to be searched
3043
* @param value Key being searched for
31-
* @return Location of the key
44+
* @return Location of the key, -1 if array is null or empty, or key not found
3245
*/
3346
@Override
3447
public <T extends Comparable<T>> int find(T[] array, T value) {
48+
if (array == null || array.length == 0) {
49+
return -1;
50+
}
3551
for (int i = 0; i < array.length; i++) {
3652
if (array[i].compareTo(value) == 0) {
3753
return i;

0 commit comments

Comments
 (0)