Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
* <p>This implementation is intended for educational purposes.</p>
*
* @see <a href="https://en.wikipedia.org/wiki/Depth-first_search">Depth First Search</a>

*/

@SuppressWarnings({"rawtypes", "unchecked"})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ private ArrayCombination() {
* @param k The desired length of each combination.
* @return A list containing all combinations of length k.
* @throws IllegalArgumentException if n or k are negative, or if k is greater than n.
*
* Complexity Analysis
* Time Complexity: O(C(n, k) * k)
* Space Complexity: O(k)
*/

public static List<List<Integer>> combination(int n, int k) {
if (k < 0 || k > n) {
throw new IllegalArgumentException("Invalid input: 0 ≤ k ≤ n is required.");
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/thealgorithms/backtracking/Combination.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,18 @@

/**
* Finds all combinations of a given array using backtracking algorithm * @author Alan Piao (<a href="https://github.com/cpiao3">git-Alan Piao</a>)
*
* Complexity Analysis
*
* Time Complexity:
* O(C(N, n) * n log n), where N is array size and n is combination length.
* The log n factor comes from TreeSet operations (add/remove).
*
* Space Complexity:
* O(C(N, n) * n) for storing all combinations +
* O(n) auxiliary space for recursion and current set.
*/

public final class Combination {
private Combination() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,22 @@
import java.util.Arrays;
import java.util.List;

/** Backtracking: pick/not-pick with reuse of candidates. */
/**
* Backtracking: pick/not-pick with reuse of candidates.
*
* Complexity Analysis
*
* Time Complexity:
* O(N^(T / min)), where N is number of candidates,
* T is target, and min is the smallest candidate value.
* In practice, it is O(P * k), where P is number of valid combinations
* and k is average combination length.
*
* Space Complexity:
* O(T / min) for recursion stack and current combination +
* O(P * (T / min)) for storing all results.
*/

public final class CombinationSum {
private CombinationSum() {
throw new UnsupportedOperationException("Utility class");
Expand Down
34 changes: 23 additions & 11 deletions src/main/java/com/thealgorithms/backtracking/CrosswordSolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,32 @@
* A class to solve a crossword puzzle using backtracking.
* Example:
* Input:
* puzzle = {
* {' ', ' ', ' '},
* {' ', ' ', ' '},
* {' ', ' ', ' '}
* }
* words = List.of("cat", "dog")
* puzzle = {
* {' ', ' ', ' '},
* {' ', ' ', ' '},
* {' ', ' ', ' '}
* }
* words = List.of("cat", "dog")
*
* Output:
* {
* {'c', 'a', 't'},
* {' ', ' ', ' '},
* {'d', 'o', 'g'}
* }
* {
* {'c', 'a', 't'},
* {' ', ' ', ' '},
* {'d', 'o', 'g'}
* }
*
* Complexity Analysis
*
* Time Complexity:
* O((2W)^W * L), where W is number of words and L is average word length.
* In the worst case, this can be approximated as O(W! * 2^W * L)
* due to trying all permutations of words with two placement directions.
*
* Space Complexity:
* O(W) for recursion stack +
* O(R * C) for the puzzle grid.
*/

public final class CrosswordSolver {
private CrosswordSolver() {
}
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/com/thealgorithms/backtracking/FloodFill.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ private FloodFill() {
* @param image The image to be filled
* @param x The x coordinate of which color is to be obtained
* @param y The y coordinate of which color is to be obtained
*
* Complexity Analysis:
*
* Time Complexity:
* O(R * C), where R is number of rows and C is number of columns.
* Each cell is visited at most once.
*
* Space Complexity:
* O(R * C) in the worst case due to recursion stack.
*/

public static int getPixel(final int[][] image, final int x, final int y) {
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/thealgorithms/backtracking/KnightsTour.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.thealgorithms.backtracking;

import java.sql.Time;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
Expand Down Expand Up @@ -66,6 +67,18 @@ public static void resetBoard() {
* @param count The current move number
* @return True if a solution is found, False otherwise
*/

/**
* Time Complexity:
*
* Worst Case: O(8^(N^2)) due to backtracking.
* Practical Complexity: Significantly reduced to near O(N^2)
* using Warnsdorff’s heuristic and pruning (orphan detection).
*
* Space Complexity:
* O(N^2) for the board and recursion stack.
*/

static boolean solve(int row, int column, int count) {
if (count > total) {
return true;
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/thealgorithms/backtracking/MColoring.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ private MColoring() {
* @param m The maximum number of allowed colors.
* @return true if the graph can be colored using M colors, false otherwise.
*/

/**
* Time Complexity:
* O(V + E), where V is number of vertices and E is number of edges.
* Each node and edge is processed once during BFS traversal.
*
* Space Complexity:
* O(V + E) for storing the graph and BFS queue.
*/

static boolean isColoringPossible(ArrayList<Node> nodes, int n, int m) {

// Visited array keeps track of whether each node has been processed.
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/thealgorithms/backtracking/MazeRecursion.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ public static int[][] solveMazeUsingSecondStrategy(int[][] map) {
* @param j The current y-coordinate of the ball (column index)
* @return True if a path is found to (6,5), otherwise false
*/

/**
* Complexity Analysis
*
* Time Complexity:
* O(R * C), where R is number of rows and C is number of columns.
* Each cell is visited at most once.
*
* Space Complexity:
* O(R * C) in the worst case due to recursion stack.
*/

private static boolean setWay(int[][] map, int i, int j) {
if (map[6][5] == 2) {
return true;
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/com/thealgorithms/backtracking/NQueens.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,21 @@ public static void placeQueens(final int queens) {
* @param columns: columns[i] = rowId where queen is placed in ith column.
* @param columnIndex: This is the column in which queen is being placed
*/

/**
* Complexity Analysis:
*
* Time Complexity:
* O(N! * N), where N is the number of queens.
* The factorial comes from placing queens column by column,
* and O(N) is for checking validity at each step.
*
* Space Complexity:
* O(N) for recursion stack and column tracking +
* O(S * N^2) for storing all valid solutions,
* where S is the number of solutions.
*/

private static void getSolution(int boardSize, List<List<String>> solutions, int[] columns, int columnIndex) {
if (columnIndex == boardSize) {
// this means that all queens have been placed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ public static List<String> generateParentheses(final int n) {
* @param close The number of closed parentheses.
* @param n The total number of pairs of parentheses.
*/

/**
* Complexity Analysis
*
* Time Complexity:
* O(Cn * n), where Cn is the nth Catalan number
* (approximately 4^n / √n). Each valid combination takes O(n) time to build.
*
* Space Complexity:
* O(Cn * n) for storing all combinations +
* O(n) recursion stack.
*/
private static void generateParenthesesHelper(List<String> result, final String current, final int open, final int close, final int n) {
if (current.length() == n * 2) {
result.add(current);
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/thealgorithms/backtracking/Permutation.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ public static <T> List<T[]> permutation(T[] arr) {
* @param result the list contains all permutations.
* @param <T> the type of elements in the array.
*/

/**
* Complexity Analysis
*
* Time Complexity:
* O(N! * N), where N is the size of the array.
* There are N! permutations and each takes O(N) time to copy.
*
* Space Complexity:
* O(N! * N) for storing all permutations +
* O(N) recursion stack.
*/

private static <T> void backtracking(T[] arr, int index, List<T[]> result) {
if (index == arr.length) {
result.add(arr.clone());
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/thealgorithms/backtracking/PowerSum.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ public int powSum(int targetSum, int power) {
* @param currentSum The current sum of powered numbers
* @return The number of valid combinations
*/

/**
* Time Complexity:
* O(2^M), where M ≈ N^(1/X).
* This corresponds to exploring all subsets of numbers whose Xth power is ≤ N.
*
* Space Complexity:
* O(M) for recursion stack.
*/

private int sumRecursive(int remainingSum, int power, int currentNumber, int currentSum) {
int newSum = currentSum + (int) Math.pow(currentNumber, power);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ public static <T> List<List<T>> generateAll(List<T> sequence) {
* @param allSubSequences contains all sequences
* @param <T> the type of elements which we generate
*/

/**
* Complexity Analysis
*
* Time Complexity:
* O(2^N * N), where N is the size of the input list.
* There are 2^N subsequences and each takes O(N) time to copy.
*
* Space Complexity:
* O(2^N * N) for storing all subsequences +
* O(N) recursion stack.
*/

private static <T> void backtrack(List<T> sequence, List<T> currentSubsequence, final int index, List<List<T>> allSubSequences) {
assert index <= sequence.size();
if (index == sequence.size()) {
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/thealgorithms/backtracking/SudokuSolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@ public static boolean solveSudoku(int[][] board) {
* @param board the Sudoku board
* @return true if solution is found, false otherwise
*/

/**
* Complexity Analysis
*
* Time Complexity:
* O(9^N), where N is the number of empty cells.
* Each empty cell can take values from 1 to 9, leading to exponential
* complexity.
*
* Space Complexity:
* O(N) for recursion stack.
*/

private static boolean solve(int[][] board) {
for (int row = 0; row < GRID_SIZE; row++) {
for (int col = 0; col < GRID_SIZE; col++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,19 @@
* Input: "AAB"
* Output: ["AAB", "ABA", "BAA"]
*
* Time Complexity: O(n! * n)
* Complexity Analysis
*
* Time Complexity:
* O(n! * n)
* - n! permutations in worst case
* - Each permutation takes O(n) to build
*
* Space Complexity:
* O(n! * n)
* - Result list stores all permutations
* - Auxiliary space: O(n) for recursion, used array, and StringBuilder
*/

public final class UniquePermutation {

private UniquePermutation() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,22 @@
* Pattern: "aabb"
* Input String: "JavaPythonPythonJava"
* Output: false
*
* Complexity Analysis
*
* Time Complexity:
* O(n^m * n)
* - n = length of input string
* - m = length of pattern
* - For each pattern character, we try all possible substrings
* - Additional O(n) cost for substring and matching operations
*
* Space Complexity:
* O(m + n)
* - O(m) recursion depth and pattern map
* - O(n) for substring mappings in strMap
*/

public final class WordPatternMatcher {
private WordPatternMatcher() {
}
Expand Down
Loading