diff --git a/src/main/java/com/thealgorithms/backtracking/BinaryTreePaths.java b/src/main/java/com/thealgorithms/backtracking/BinaryTreePaths.java new file mode 100644 index 000000000000..df8bd25c3efe --- /dev/null +++ b/src/main/java/com/thealgorithms/backtracking/BinaryTreePaths.java @@ -0,0 +1,46 @@ +package com.thealgorithms.backtracking; + +import java.util.ArrayList; +import java.util.List; + +public class BinaryTreePaths { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int val) { + this.val = val; + } + } + + public List binaryTreePaths(TreeNode root) { + List list = new ArrayList<>(); + if (root == null) { + return list; + } + dfs(root, "", list); + return list; + } + + private void dfs(TreeNode node, String path, List list) { + if (node == null) { + return; + } + + if (path.isEmpty()) { + path = Integer.toString(node.val); + } else { + path += "->" + node.val; + } + + if (node.left == null && node.right == null) { + list.add(path); + return; + } + + dfs(node.left, path, list); + dfs(node.right, path, list); + } +} diff --git a/src/main/java/com/thealgorithms/recursion/Factorial.java b/src/main/java/com/thealgorithms/recursion/Factorial.java new file mode 100644 index 000000000000..d080703d99b8 --- /dev/null +++ b/src/main/java/com/thealgorithms/recursion/Factorial.java @@ -0,0 +1,32 @@ +package com.thealgorithms.recursion; + +/** + * Implementation of factorial using recursion. + *

+ * The factorial of a non-negative integer n is defined as: + * n! = n × (n-1) × (n-2) × ... × 1, with 0! = 1. + */ +public final class Factorial { + + // Private constructor to prevent instantiation + private Factorial() { + throw new UnsupportedOperationException("Utility class"); + } + + /** + * Calculates factorial recursively. + * + * @param n non-negative integer + * @return factorial of n + * @throws IllegalArgumentException if n is negative + */ + public static long factorial(int n) { + if (n < 0) { + throw new IllegalArgumentException("Number must be non-negative"); + } + if (n == 0 || n == 1) { + return 1; + } + return n * factorial(n - 1); + } +} diff --git a/src/main/java/com/thealgorithms/strings/StringRotation.java b/src/main/java/com/thealgorithms/strings/StringRotation.java new file mode 100644 index 000000000000..30a5725477a8 --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/StringRotation.java @@ -0,0 +1,28 @@ +package com.thealgorithms.strings; + +public final class StringRotation { + + private StringRotation() { + throw new UnsupportedOperationException("Utility class"); + } + + /** + * Checks if str2 is a rotation of str1. + * + * @param str1 the original string + * @param str2 the string to check for rotation + * @return true if str2 is a rotation of str1, false otherwise + */ + public static boolean isRotation(String str1, String str2) { + if (str1 == null || str2 == null) { + return false; + } + + if (str1.length() != str2.length()) { + return false; + } + + String concatenated = str1 + str1; + return concatenated.contains(str2); + } +} diff --git a/src/test/java/com/thealgorithms/backtracking/BinaryTreePathsTest.java b/src/test/java/com/thealgorithms/backtracking/BinaryTreePathsTest.java new file mode 100644 index 000000000000..7367a1d7751d --- /dev/null +++ b/src/test/java/com/thealgorithms/backtracking/BinaryTreePathsTest.java @@ -0,0 +1,43 @@ +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import org.junit.jupiter.api.Test; + +public class BinaryTreePathsTest { + + @Test + void testBinaryTreePathsBasic() { + BinaryTreePaths.TreeNode root = new BinaryTreePaths.TreeNode(1); + root.left = new BinaryTreePaths.TreeNode(2); + root.right = new BinaryTreePaths.TreeNode(3); + root.left.right = new BinaryTreePaths.TreeNode(5); + + BinaryTreePaths solver = new BinaryTreePaths(); + List result = solver.binaryTreePaths(root); + + assertEquals(2, result.size()); + assertTrue(result.contains("1->2->5")); + assertTrue(result.contains("1->3")); + } + + @Test + void testSingleNodeTree() { + BinaryTreePaths.TreeNode root = new BinaryTreePaths.TreeNode(42); + + BinaryTreePaths solver = new BinaryTreePaths(); + List result = solver.binaryTreePaths(root); + + assertEquals(List.of("42"), result); + } + + @Test + void testEmptyTree() { + BinaryTreePaths solver = new BinaryTreePaths(); + List result = solver.binaryTreePaths(null); + + assertTrue(result.isEmpty()); + } +} diff --git a/src/test/java/com/thealgorithms/strings/StringRotationTest.java b/src/test/java/com/thealgorithms/strings/StringRotationTest.java new file mode 100644 index 000000000000..b76df428277c --- /dev/null +++ b/src/test/java/com/thealgorithms/strings/StringRotationTest.java @@ -0,0 +1,30 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class StringRotationTest { + + @Test + void testValidRotation() { + assertTrue(StringRotation.isRotation("waterbottle", "erbottlewat")); + } + + @Test + void testInvalidRotation() { + assertFalse(StringRotation.isRotation("hello", "world")); + } + + @Test + void testDifferentLengths() { + assertFalse(StringRotation.isRotation("abc", "abcd")); + } + + @Test + void testNullInput() { + assertFalse(StringRotation.isRotation(null, "abc")); + assertFalse(StringRotation.isRotation("abc", null)); + } +}