Skip to content

Commit 6d5a57b

Browse files
authored
Merge branch 'master' into testing/AbsoluteValueTest
2 parents 46d9c78 + ca7c77f commit 6d5a57b

File tree

5 files changed

+110
-67
lines changed

5 files changed

+110
-67
lines changed
Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,65 @@
11
package com.thealgorithms.datastructures.disjointsetunion;
22

33
/**
4-
* Disjoint Set Union or DSU is useful for solving problems related to connected components,
5-
* cycle detection in graphs, and maintaining relationships in disjoint sets of data.
6-
* It is commonly employed in graph algorithms and problems.
4+
* Disjoint Set Union (DSU), also known as Union-Find, is a data structure that tracks a set of elements
5+
* partitioned into disjoint (non-overlapping) subsets. It supports two primary operations efficiently:
76
*
8-
* @see <a href="https://en.wikipedia.org/wiki/Disjoint-set_data_structure">Disjoint Set Union</a>
7+
* <ul>
8+
* <li>Find: Determine which subset a particular element belongs to.</li>
9+
* <li>Union: Merge two subsets into a single subset.</li>
10+
* </ul>
11+
*
12+
* @see <a href="https://en.wikipedia.org/wiki/Disjoint-set_data_structure">Disjoint Set Union (Wikipedia)</a>
913
*/
1014
public class DisjointSetUnion<T> {
1115

1216
/**
13-
* Creates a new node of DSU with parent initialised as same node
17+
* Creates a new disjoint set containing the single specified element.
18+
*
19+
* @param value the element to be placed in a new singleton set
20+
* @return a node representing the new set
1421
*/
15-
public Node<T> makeSet(final T x) {
16-
return new Node<T>(x);
22+
public Node<T> makeSet(final T value) {
23+
return new Node<>(value);
1724
}
1825

1926
/**
20-
* Finds and returns the representative (root) element of the set to which a given element belongs.
21-
* This operation uses path compression to optimize future findSet operations.
27+
* Finds and returns the representative (root) of the set containing the given node.
28+
* This method applies path compression to flatten the tree structure for future efficiency.
29+
*
30+
* @param node the node whose set representative is to be found
31+
* @return the representative (root) node of the set
2232
*/
2333
public Node<T> findSet(Node<T> node) {
24-
while (node != node.parent) {
25-
node = node.parent;
34+
if (node != node.parent) {
35+
node.parent = findSet(node.parent);
2636
}
27-
return node;
37+
return node.parent;
2838
}
2939

3040
/**
31-
* Unions two sets by merging their representative elements. The merge is performed based on the rank of each set
32-
* to ensure efficient merging and path compression to optimize future findSet operations.
41+
* Merges the sets containing the two given nodes. Union by rank is used to attach the smaller tree under the larger one.
42+
* If both sets have the same rank, one becomes the parent and its rank is incremented.
43+
*
44+
* @param x a node in the first set
45+
* @param y a node in the second set
3346
*/
34-
public void unionSets(final Node<T> x, final Node<T> y) {
35-
Node<T> nx = findSet(x);
36-
Node<T> ny = findSet(y);
47+
public void unionSets(Node<T> x, Node<T> y) {
48+
Node<T> rootX = findSet(x);
49+
Node<T> rootY = findSet(y);
3750

38-
if (nx == ny) {
39-
return; // Both elements already belong to the same set.
51+
if (rootX == rootY) {
52+
return; // They are already in the same set
4053
}
4154
// Merging happens based on rank of node, this is done to avoid long chaining of nodes and reduce time
4255
// to find root of the component. Idea is to attach small components in big, instead of other way around.
43-
if (nx.rank > ny.rank) {
44-
ny.parent = nx;
45-
} else if (ny.rank > nx.rank) {
46-
nx.parent = ny;
56+
if (rootX.rank > rootY.rank) {
57+
rootY.parent = rootX;
58+
} else if (rootY.rank > rootX.rank) {
59+
rootX.parent = rootY;
4760
} else {
48-
// Both sets have the same rank; choose one as the parent and increment the rank.
49-
ny.parent = nx;
50-
nx.rank++;
61+
rootY.parent = rootX;
62+
rootX.rank++;
5163
}
5264
}
5365
}
Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,39 @@
11
package com.thealgorithms.dynamicprogramming;
2-
/*
3-
The Sum of Subset problem determines whether a subset of elements from a
4-
given array sums up to a specific target value.
5-
*/
2+
3+
/**
4+
* Utility class for solving the Subset Sum problem using a space-optimized dynamic programming approach.
5+
*
6+
* <p>This algorithm determines whether any subset of a given array sums up to a specific target value.</p>
7+
*
8+
* <p><b>Time Complexity:</b> O(n * sum)</p>
9+
* <p><b>Space Complexity:</b> O(sum)</p>
10+
*/
611
public final class SubsetSumSpaceOptimized {
712
private SubsetSumSpaceOptimized() {
813
}
14+
915
/**
10-
* This method checks whether the subset of an array
11-
* contains a given sum or not. This is an space
12-
* optimized solution using 1D boolean array
13-
* Time Complexity: O(n * sum), Space complexity: O(sum)
16+
* Determines whether there exists a subset of the given array that adds up to the specified sum.
17+
* This method uses a space-optimized dynamic programming approach with a 1D boolean array.
1418
*
15-
* @param arr An array containing integers
16-
* @param sum The target sum of the subset
17-
* @return True or False
19+
* @param nums The array of non-negative integers
20+
* @param targetSum The desired subset sum
21+
* @return {@code true} if such a subset exists, {@code false} otherwise
1822
*/
19-
public static boolean isSubsetSum(int[] arr, int sum) {
20-
int n = arr.length;
21-
// Declare the boolean array with size sum + 1
22-
boolean[] dp = new boolean[sum + 1];
23+
public static boolean isSubsetSum(int[] nums, int targetSum) {
24+
if (targetSum < 0) {
25+
return false; // Subset sum can't be negative
26+
}
2327

24-
// Initialize the first element as true
25-
dp[0] = true;
28+
boolean[] dp = new boolean[targetSum + 1];
29+
dp[0] = true; // Empty subset always sums to 0
2630

27-
// Find the subset sum using 1D array
28-
for (int i = 0; i < n; i++) {
29-
for (int j = sum; j >= arr[i]; j--) {
30-
dp[j] = dp[j] || dp[j - arr[i]];
31+
for (int number : nums) {
32+
for (int j = targetSum; j >= number; j--) {
33+
dp[j] = dp[j] || dp[j - number];
3134
}
3235
}
33-
return dp[sum];
36+
37+
return dp[targetSum];
3438
}
3539
}

src/main/java/com/thealgorithms/matrix/MedianOfMatrix.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@ private MedianOfMatrix() {
1414
}
1515

1616
public static int median(Iterable<List<Integer>> matrix) {
17-
// Flatten the matrix into a 1D list
18-
List<Integer> linear = new ArrayList<>();
17+
List<Integer> flattened = new ArrayList<>();
18+
1919
for (List<Integer> row : matrix) {
20-
linear.addAll(row);
20+
if (row != null) {
21+
flattened.addAll(row);
22+
}
2123
}
2224

23-
// Sort the 1D list
24-
Collections.sort(linear);
25-
26-
// Calculate the middle index
27-
int mid = (0 + linear.size() - 1) / 2;
25+
if (flattened.isEmpty()) {
26+
throw new IllegalArgumentException("Matrix must contain at least one element.");
27+
}
2828

29-
// Return the median
30-
return linear.get(mid);
29+
Collections.sort(flattened);
30+
return flattened.get((flattened.size() - 1) / 2);
3131
}
3232
}

src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,29 @@
22

33
import java.util.Stack;
44

5+
/**
6+
* Utility class for converting a non-negative decimal (base-10) integer
7+
* to its representation in another radix (base) between 2 and 16, inclusive.
8+
*
9+
* <p>This class uses a stack-based approach to reverse the digits obtained from
10+
* successive divisions by the target radix.
11+
*
12+
* <p>This class cannot be instantiated.</p>
13+
*/
514
public final class DecimalToAnyUsingStack {
15+
616
private DecimalToAnyUsingStack() {
717
}
818

19+
private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
20+
921
/**
1022
* Convert a decimal number to another radix.
1123
*
1224
* @param number the number to be converted
1325
* @param radix the radix
1426
* @return the number represented in the new radix as a String
15-
* @throws IllegalArgumentException if <tt>number</tt> is negative or <tt>radix</tt> is not between 2 and 16 inclusive
27+
* @throws IllegalArgumentException if number is negative or radix is not between 2 and 16 inclusive
1628
*/
1729
public static String convert(int number, int radix) {
1830
if (number < 0) {
@@ -26,18 +38,17 @@ public static String convert(int number, int radix) {
2638
return "0";
2739
}
2840

29-
char[] tables = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
30-
31-
Stack<Character> bits = new Stack<>();
41+
Stack<Character> digitStack = new Stack<>();
3242
while (number > 0) {
33-
bits.push(tables[number % radix]);
34-
number = number / radix;
43+
digitStack.push(DIGITS[number % radix]);
44+
number /= radix;
3545
}
3646

37-
StringBuilder result = new StringBuilder();
38-
while (!bits.isEmpty()) {
39-
result.append(bits.pop());
47+
StringBuilder result = new StringBuilder(digitStack.size());
48+
while (!digitStack.isEmpty()) {
49+
result.append(digitStack.pop());
4050
}
51+
4152
return result.toString();
4253
}
4354
}

src/test/java/com/thealgorithms/matrix/MedianOfMatrixTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.thealgorithms.matrix;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
45

56
import java.util.ArrayList;
67
import java.util.Arrays;
8+
import java.util.Collections;
79
import java.util.List;
810
import org.junit.jupiter.api.Test;
911

@@ -31,4 +33,18 @@ public void testMedianWithEvenNumberOfElements() {
3133

3234
assertEquals(2, result);
3335
}
36+
37+
@Test
38+
public void testMedianSingleElement() {
39+
List<List<Integer>> matrix = new ArrayList<>();
40+
matrix.add(List.of(1));
41+
42+
assertEquals(1, MedianOfMatrix.median(matrix));
43+
}
44+
45+
@Test
46+
void testEmptyMatrixThrowsException() {
47+
Iterable<List<Integer>> emptyMatrix = Collections.emptyList();
48+
assertThrows(IllegalArgumentException.class, () -> MedianOfMatrix.median(emptyMatrix), "Expected median() to throw, but it didn't");
49+
}
3450
}

0 commit comments

Comments
 (0)