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
167 changes: 55 additions & 112 deletions src/main/java/com/thealgorithms/backtracking/SudokuSolver.java
Original file line number Diff line number Diff line change
@@ -1,157 +1,100 @@
package com.thealgorithms.backtracking;

/**
* Sudoku Solver using Backtracking Algorithm
* Solves a 9x9 Sudoku puzzle by filling empty cells with valid digits (1-9)
* The {@code SudokuSolver} class provides a solution to Sudoku puzzles.
* Solves the puzzle by a depth-first backtracking algorithm.
*
* @author Navadeep0007
* <p>The algorithm fills empty cells (represented by 0) by trying digits 1-9 and
* recursively verifying if they lead to a valid solution.
*
* <p>Time Complexity: O(9^{n*n}) where n is the dimension of the grid.
* Space Complexity: O(n*n) to store the board and recursion stack.
*
* @author subhammohanty-sys
*/
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
* Entry point to solve the Sudoku puzzle. Performs a pre-validation check
* before starting the recursion.
*
* @param board 9x9 Sudoku board with 0 representing empty cells
* @return true if puzzle is solved, false otherwise
* @param board 2D array representing the Sudoku grid (0 for empty cells).
* @return true if the board is solvable, false otherwise.
*/
public static boolean solveSudoku(int[][] board) {
if (board == null || board.length != GRID_SIZE) {
if (board == null || board.length != 9) {
return false;
}

for (int row = 0; row < GRID_SIZE; row++) {
if (board[row].length != GRID_SIZE) {
for (int[] row : board) {
if (row == null || row.length != 9) {
return false;
}
}

if (!isBoardValid(board)) {
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;
}
private static boolean isBoardValid(int[][] board) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] != 0) {
int num = board[i][j];
board[i][j] = 0;
if (!isValid(board, i, j, num)) {
return false;
}
return false;
board[i][j] = num;
}
}
}
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;
private static boolean isValid(int[][] board, int row, int col, int num) {
for (int i = 0; i < 9; i++) {
if (board[i][col] == num || board[row][i] == num) {
return false;
}
}
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;
int sr = row / 3 * 3;
int sc = col / 3 * 3;

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;
for (int i = sr; i < sr + 3; i++) {
for (int j = sc; j < sc + 3; j++) {
if (board[i][j] == num) {
return false;
}
}
}
return false;
return true;
}

/**
* 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("|");
private static boolean solve(int[][] board) {
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
if (board[row][col] == 0) {
for (int num = 1; num <= 9; num++) {
if (isValid(board, row, col, num)) {
board[row][col] = num;
if (solve(board)) {
return true;
}
board[row][col] = 0;
}
}
return false;
}
System.out.print(board[row][col]);
}
System.out.println();
}
return true;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
/**
* [Brief description of what the algorithm does]
* <p>
* Time Complexity: O(n) [or appropriate complexity]
* Space Complexity: O(n)
* @author Reshma Kakkirala
*/
package com.thealgorithms.conversions;

import java.util.Arrays;
Expand All @@ -13,6 +6,12 @@
import java.util.Scanner;

/**
* [Brief description of what the algorithm does]
* <p>
* Time Complexity: O(n) [or appropriate complexity] Space Complexity: O(n)
*
* @author Reshma Kakkirala
*
* Class for converting from "any" base to "any" other base, when "any" means
* from 2-36. Works by going from base 1 to decimal to base 2. Includes
* auxiliary method for determining whether a number is valid for a given base.
Expand All @@ -21,6 +20,7 @@
* @version 2017.10.10
*/
public final class AnyBaseToAnyBase {

private AnyBaseToAnyBase() {
}

Expand Down Expand Up @@ -70,44 +70,7 @@ public static void main(String[] args) {
* Checks if a number (as a String) is valid for a given base.
*/
public static boolean validForBase(String n, int base) {
char[] validDigits = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
};
char[] validDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
// digitsForBase contains all the valid digits for the base given
char[] digitsForBase = Arrays.copyOfRange(validDigits, 0, base);

Expand Down
35 changes: 16 additions & 19 deletions src/main/java/com/thealgorithms/searches/InterpolationSearch.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
/**
* Interpolation Search estimates the position of the target value
* based on the distribution of values.
*
* Example:
* Input: [10, 20, 30, 40], target = 30
* Output: Index = 2
*
* Time Complexity: O(log log n) (average case)
* Space Complexity: O(1)
*/
package com.thealgorithms.searches;

/**
* InterpolationSearch is an algorithm that searches for a target value within a sorted array
* by estimating the position based on the values at the corners of the current search range.
* Interpolation Search estimates the position of the target value based on the
* distribution of values.
*
* Example: Input: [10, 20, 30, 40], target = 30 Output: Index = 2
*
* Time Complexity: O(log log n) (average case) Space Complexity: O(1)
*
* InterpolationSearch is an algorithm that searches for a target value within a
* sorted array by estimating the position based on the values at the corners of
* the current search range.
*
* <p>
* The performance of this algorithm can vary:
* - Worst-case performance: O(n)
* - Best-case performance: O(1)
* - Average performance: O(log(log(n))) if the elements are uniformly distributed; otherwise O(n)
* - Worst-case space complexity: O(1)
* The performance of this algorithm can vary: - Worst-case performance: O(n) -
* Best-case performance: O(1) - Average performance: O(log(log(n))) if the
* elements are uniformly distributed; otherwise O(n) - Worst-case space
* complexity: O(1)
* </p>
*
* <p>
Expand All @@ -32,7 +28,8 @@
class InterpolationSearch {

/**
* Finds the index of the specified key in a sorted array using interpolation search.
* Finds the index of the specified key in a sorted array using
* interpolation search.
*
* @param array The sorted array to search.
* @param key The value to search for.
Expand Down
35 changes: 14 additions & 21 deletions src/main/java/com/thealgorithms/searches/LinearSearch.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,23 @@
/**
* 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 a simple searching algorithm that checks
* each element of the array sequentially until the target
* value is found or the array ends.
* 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)
*
* 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.
*
* Time Complexity:
* - Best case: O(1)
* - Average case: O(n)
* - Worst case: O(n)
* Time Complexity: - Best case: O(1) - Average case: O(n) - Worst case: O(n)
*
* Space Complexity: O(1)
*
Expand All @@ -41,7 +33,8 @@ public class LinearSearch implements SearchAlgorithm {
*
* @param array List to be searched
* @param value Key being searched for
* @return Location of the key, -1 if array is null or empty, or key not found
* @return Location of the key, -1 if array is null or empty, or key not
* found
*/
@Override
public <T extends Comparable<T>> int find(T[] array, T value) {
Expand Down
Loading
Loading