15 Backtracking Question
15 Backtracking Question
BY: coding_error1
1. N-Queens Problem
Problem: Place N queens on an N×N chessboard so that no two queens attack each other.
Python Solution
def solve_n_queens(n):
def is_safe(board, row, col):
# Check column
for i in range(row):
if board[i][col] == 1:
return False
return True
return False
BY: coding_error1
# Example usage
result = solve_n_queens(4)
if result:
for row in result:
print(row)
Java Solution
public class NQueens {
public static boolean solveNQueens(int n) {
int[][] board = new int[n][n];
if (backtrack(board, 0, n)) {
printBoard(board, n);
return true;
}
return false;
}
private static boolean isSafe(int[][] board, int row, int col, int n) {
// Check column
for (int i = 0; i < row; i++) {
if (board[i][col] == 1) return false;
}
// Check diagonals
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (board[i][j] == 1) return false;
}
return true;
}
C++ Solution
BY: coding_error1
#include <iostream>
#include <vector>
using namespace std;
class NQueens {
public:
bool solveNQueens(int n) {
vector<vector<int>> board(n, vector<int>(n, 0));
if (backtrack(board, 0, n)) {
printBoard(board, n);
return true;
}
return false;
}
private:
bool isSafe(vector<vector<int>>& board, int row, int col, int n) {
// Check column
for (int i = 0; i < row; i++) {
if (board[i][col] == 1) return false;
}
// Check diagonals
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (board[i][j] == 1) return false;
}
return true;
}
BY: coding_error1
Common Backtracking Template
def backtrack(parameters):
# Base case
if condition_met:
process_solution()
return
# Recursively explore
backtrack(updated_parameters)
• N-Queens: O(N!)
• Sudoku: O(9^(n*n)) where n is empty cells
• Permutations: O(N! × N)
• Subsets: O(2^N × N)
• Combination Sum: O(2^target)
Space Complexity
Optimization Techniques
2. Sudoku Solver
Problem: Fill a 9×9 Sudoku grid following the standard rules.
Python Solution
def solve_sudoku(board):
def is_valid(board, row, col, num):
# Check row
for j in range(9):
if board[row][j] == num:
return False
# Check column
for i in range(9):
BY: coding_error1
if board[i][col] == num:
return False
return True
def backtrack():
for i in range(9):
for j in range(9):
if board[i][j] == 0:
for num in range(1, 10):
if is_valid(board, i, j, num):
board[i][j] = num
if backtrack():
return True
board[i][j] = 0
return False
return True
return backtrack()
# Example usage
board = [
[5,3,0,0,7,0,0,0,0],
[6,0,0,1,9,5,0,0,0],
[0,9,8,0,0,0,0,6,0],
[8,0,0,0,6,0,0,0,3],
[4,0,0,8,0,3,0,0,1],
[7,0,0,0,2,0,0,0,6],
[0,6,0,0,0,0,2,8,0],
[0,0,0,4,1,9,0,0,5],
[0,0,0,0,8,0,0,7,9]
]
if solve_sudoku(board):
for row in board:
print(row)
Java Solution
public class SudokuSolver {
public static boolean solveSudoku(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 (solveSudoku(board)) return true;
board[row][col] = 0;
}
}
return false;
}
BY: coding_error1
}
}
return true;
}
private static boolean isValid(int[][] board, int row, int col, int
num) {
// Check row and column
for (int i = 0; i < 9; i++) {
if (board[row][i] == num || board[i][col] == num) return false;
}
C++ Solution
#include <vector>
using namespace std;
class SudokuSolver {
public:
bool solveSudoku(vector<vector<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 (solveSudoku(board)) return true;
board[row][col] = 0;
}
}
return false;
}
}
}
return true;
}
private:
bool isValid(vector<vector<int>>& board, int row, int col, int num) {
// Check row and column
for (int i = 0; i < 9; i++) {
if (board[row][i] == num || board[i][col] == num) return false;
}
BY: coding_error1
for (int j = startCol; j < startCol + 3; j++) {
if (board[i][j] == num) return false;
}
}
return true;
}
};
Python Solution
def permutations(nums):
result = []
def backtrack(current):
if len(current) == len(nums):
result.append(current[:])
return
backtrack([])
return result
# Example usage
print(permutations([1, 2, 3]))
Java Solution
import java.util.*;
BY: coding_error1
}
}
}
C++ Solution
#include <vector>
#include <algorithm>
using namespace std;
class Permutations {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> result;
vector<int> current;
backtrack(nums, current, result);
return result;
}
private:
void backtrack(vector<int>& nums, vector<int>& current,
vector<vector<int>>& result) {
if (current.size() == nums.size()) {
result.push_back(current);
return;
}
4. Combination Sum
Problem: Find all unique combinations where the candidate numbers sum to target.
Python Solution
def combination_sum(candidates, target):
result = []
BY: coding_error1
backtrack(0, [], target)
return result
# Example usage
print(combination_sum([2, 3, 6, 7], 7))
Java Solution
import java.util.*;
C++ Solution
#include <vector>
using namespace std;
class CombinationSum {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target)
{
vector<vector<int>> result;
vector<int> current;
backtrack(candidates, target, 0, current, result);
return result;
}
private:
void backtrack(vector<int>& candidates, int remaining, int start,
vector<int>& current, vector<vector<int>>& result) {
if (remaining == 0) {
result.push_back(current);
return;
BY: coding_error1
}
5. Word Search
Problem: Find if a word exists in a 2D board of characters.
Python Solution
def word_search(board, word):
if not board or not board[0]:
return False
if (row < 0 or row >= rows or col < 0 or col >= cols or
board[row][col] != word[index]):
return False
# Mark as visited
temp = board[row][col]
board[row][col] = '#'
for i in range(rows):
for j in range(cols):
if backtrack(i, j, 0):
return True
return False
# Example usage
board = [
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
BY: coding_error1
]
print(word_search(board, "ABCCED")) # True
Java Solution
public class WordSearch {
public static boolean exist(char[][] board, String word) {
if (board == null || board.length == 0) return false;
board[row][col] = temp;
return found;
}
}
C++ Solution
#include <vector>
#include <string>
using namespace std;
class WordSearch {
public:
bool exist(vector<vector<char>>& board, string word) {
if (board.empty()) return false;
BY: coding_error1
}
private:
bool backtrack(vector<vector<char>>& board, string& word, int row, int
col, int index) {
if (index == word.length()) return true;
board[row][col] = temp;
return found;
}
};
6. Palindrome Partitioning
Problem: Partition a string such that every substring is a palindrome.
Python Solution
def palindrome_partition(s):
result = []
def is_palindrome(string):
return string == string[::-1]
backtrack(0, [])
return result
# Example usage
print(palindrome_partition("aab"))
Java Solution
import java.util.*;
BY: coding_error1
public class PalindromePartition {
public static List<List<String>> partition(String s) {
List<List<String>> result = new ArrayList<>();
backtrack(s, 0, new ArrayList<>(), result);
return result;
}
C++ Solution
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class PalindromePartition {
public:
vector<vector<string>> partition(string s) {
vector<vector<string>> result;
vector<string> current;
backtrack(s, 0, current, result);
return result;
}
private:
void backtrack(string& s, int start, vector<string>& current,
vector<vector<string>>& result) {
if (start == s.length()) {
result.push_back(current);
return;
}
BY: coding_error1
if (isPalindrome(substring)) {
current.push_back(substring);
backtrack(s, end, current, result);
current.pop_back();
}
}
}
bool isPalindrome(string& s) {
int left = 0, right = s.length() - 1;
while (left < right) {
if (s[left++] != s[right--]) return false;
}
return true;
}
};
7. Subset Generation
Problem: Generate all possible subsets of a given set.
Python Solution
def subsets(nums):
result = []
backtrack(0, [])
return result
# Example usage
print(subsets([1, 2, 3]))
Java Solution
import java.util.*;
BY: coding_error1
backtrack(nums, i + 1, current, result);
current.remove(current.size() - 1);
}
}
}
C++ Solution
#include <vector>
using namespace std;
class Subsets {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> result;
vector<int> current;
backtrack(nums, 0, current, result);
return result;
}
private:
void backtrack(vector<int>& nums, int start, vector<int>& current,
vector<vector<int>>& result) {
result.push_back(current);
Python Solution
def letter_combinations(digits):
if not digits:
return []
phone = {
'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl',
'6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'
}
result = []
BY: coding_error1
backtrack(0, "")
return result
# Example usage
print(letter_combinations("23"))
Java Solution
import java.util.*;
C++ Solution
#include <vector>
#include <string>
using namespace std;
class LetterCombinations {
public:
vector<string> letterCombinations(string digits) {
if (digits.empty()) return {};
BY: coding_error1
private:
void backtrack(string& digits, int index, string& current,
vector<string>& result, vector<string>& phone) {
if (index == digits.length()) {
result.push_back(current);
return;
}
9. Rat in a Maze
Problem: Find path for a rat to reach from source to destination in a maze.
Python Solution
def rat_in_maze(maze):
n = len(maze)
solution = [[0] * n for _ in range(n)]
if is_safe(x, y):
solution[x][y] = 1
# Move right
if backtrack(x, y + 1):
return True
# Move down
if backtrack(x + 1, y):
return True
# Backtrack
solution[x][y] = 0
return False
return False
if backtrack(0, 0):
return solution
return None
# Example usage
maze = [
BY: coding_error1
[1, 0, 0, 0],
[1, 1, 0, 1],
[0, 1, 0, 0],
[1, 1, 1, 1]
]
result = rat_in_maze(maze)
if result:
for row in result:
print(row)
Java Solution
public class RatInMaze {
public static boolean solveMaze(int[][] maze) {
int n = maze.length;
int[][] solution = new int[n][n];
if (isSafe(maze, x, y, n)) {
solution[x][y] = 1;
// Move right
if (backtrack(maze, x, y + 1, solution, n)) return true;
// Move down
if (backtrack(maze, x + 1, y, solution, n)) return true;
// Backtrack
solution[x][y] = 0;
return false;
}
return false;
}
BY: coding_error1
C++ Solution
#include <vector>
#include <iostream>
using namespace std;
class RatInMaze {
public:
bool solveMaze(vector<vector<int>>& maze) {
int n = maze.size();
vector<vector<int>> solution(n, vector<int>(n, 0));
private:
bool isSafe(vector<vector<int>>& maze, int x, int y, int n) {
return x >= 0 && x < n && y >= 0 && y < n && maze[x][y] == 1;
}
if (isSafe(maze, x, y, n)) {
solution[x][y] = 1;
// Move right
if (backtrack(maze, x, y + 1, solution, n)) return true;
// Move down
if (backtrack(maze, x + 1, y, solution, n)) return true;
// Backtrack
solution[x][y] = 0;
return false;
}
return false;
}
BY: coding_error1
Problem: Color the vertices of a graph such that no two adjacent vertices have the same
color.
Python Solution
def graph_coloring(graph, m):
n = len(graph)
colors = [0] * n
def backtrack(vertex):
if vertex == n:
return True
return False
if backtrack(0):
return colors
return None
# Example usage
graph = [
[0, 1, 1, 1],
[1, 0, 1, 0],
[1, 1, 0, 1],
[1, 0, 1, 0]
]
result = graph_coloring(graph, 3)
print(result) # [1, 2, 3, 2]
Java Solution
public class GraphColoring {
public static boolean graphColoring(int[][] graph, int m) {
int n = graph.length;
int[] colors = new int[n];
BY: coding_error1
if (graph[vertex][i] == 1 && colors[i] == color) return false;
}
return true;
}
C++ Solution
#include <vector>
#include <iostream>
using namespace std;
class GraphColoring {
public:
bool graphColoring(vector<vector<int>>& graph, int m) {
int n = graph.size();
vector<int> colors(n, 0);
private:
bool isSafe(vector<vector<int>>& graph, int vertex, int color,
vector<int>& colors, int n) {
for (int i = 0; i < n; i++) {
if (graph[vertex][i] == 1 && colors[i] == color) return false;
}
return true;
}
BY: coding_error1
for (int color = 1; color <= m; color++) {
if (isSafe(graph, vertex, color, colors, n)) {
colors[vertex] = color;
if (backtrack(graph, m, colors, vertex + 1, n)) return
true;
colors[vertex] = 0;
}
}
return false;
}
Python Solution
def knights_tour(n):
# Knight moves
moves = [(2, 1), (1, 2), (-1, 2), (-2, 1),
(-2, -1), (-1, -2), (1, -2), (2, -1)]
if move_count == n * n - 1:
return True
board[x][y] = -1
return False
if backtrack(0, 0, 0):
return board
return None
BY: coding_error1
print(row)
Java Solution
public class KnightsTour {
private static int[] moveX = {2, 1, -1, -2, -2, -1, 1, 2};
private static int[] moveY = {1, 2, 2, 1, -1, -2, -2, -1};
board[x][y] = -1;
return false;
}
C++ Solution
BY: coding_error1
#include <vector>
#include <iostream>
#include <iomanip>
using namespace std;
class KnightsTour {
private:
int moveX[8] = {2, 1, -1, -2, -2, -1, 1, 2};
int moveY[8] = {1, 2, 2, 1, -1, -2, -2, -1};
public:
bool knightsTour(int n) {
vector<vector<int>> board(n, vector<int>(n, -1));
private:
bool isSafe(int x, int y, vector<vector<int>>& board, int n) {
return x >= 0 && x < n && y >= 0 && y < n && board[x][y] == -1;
}
board[x][y] = -1;
return false;
}
BY: coding_error1
Python Solution
def hamilton_path(graph):
n = len(graph)
path = []
visited = [False] * n
def backtrack(vertex):
path.append(vertex)
visited[vertex] = True
if len(path) == n:
return True
path.pop()
visited[vertex] = False
return False
return None
# Example usage
graph = [
[0, 1, 0, 1, 0],
[1, 0, 1, 1, 1],
[0, 1, 0, 0, 1],
[1, 1, 0, 0, 1],
[0, 1, 1, 1, 0]
]
result = hamilton_path(graph)
print(result)
Java Solution
import java.util.*;
BY: coding_error1
}
return null;
}
path.remove(path.size() - 1);
visited[vertex] = false;
return false;
}
}
C++ Solution
#include <vector>
using namespace std;
class HamiltonPath {
public:
vector<int> hamiltonPath(vector<vector<int>>& graph) {
int n = graph.size();
vector<int> path;
vector<bool> visited(n, false);
private:
bool backtrack(vector<vector<int>>& graph, int vertex, vector<int>&
path,
vector<bool>& visited, int n) {
path.push_back(vertex);
visited[vertex] = true;
BY: coding_error1
}
}
path.pop_back();
visited[vertex] = false;
return false;
}
};
Python Solution
def add_operators(num, target):
result = []
if index == 0:
backtrack(i + 1, current_str, current_num, current_num)
else:
# Addition
backtrack(i + 1, expression + '+' + current_str,
value + current_num, current_num)
# Subtraction
backtrack(i + 1, expression + '-' + current_str,
value - current_num, -current_num)
# Multiplication
backtrack(i + 1, expression + '*' + current_str,
value - prev_operand + prev_operand * current_num,
prev_operand * current_num)
backtrack(0, "", 0, 0)
return result
# Example usage
print(add_operators("123", 6)) # ["1+2+3", "1*2*3"]
Java Solution
import java.util.*;
BY: coding_error1
public class ExpressionAddOperators {
public static List<String> addOperators(String num, int target) {
List<String> result = new ArrayList<>();
backtrack(num, target, 0, "", 0, 0, result);
return result;
}
private static void backtrack(String num, int target, int index, String
expression,
long value, long prevOperand, List<String>
result) {
if (index == num.length()) {
if (value == target) {
result.add(expression);
}
return;
}
if (index == 0) {
backtrack(num, target, i + 1, currentStr, currentNum,
currentNum, result);
} else {
backtrack(num, target, i + 1, expression + "+" +
currentStr,
value + currentNum, currentNum, result);
C++ Solution
#include <vector>
#include <string>
using namespace std;
class ExpressionAddOperators {
public:
vector<string> addOperators(string num, int target) {
vector<string> result;
backtrack(num, target, 0, "", 0, 0, result);
return result;
}
BY: coding_error1
private:
void backtrack(string& num, int target, int index, string expression,
long long value, long long prevOperand, vector<string>&
result) {
if (index == num.length()) {
if (value == target) {
result.push_back(expression);
}
return;
}
if (index == 0) {
backtrack(num, target, i + 1, currentStr, currentNum,
currentNum, result);
} else {
backtrack(num, target, i + 1, expression + "+" +
currentStr,
value + currentNum, currentNum, result);
Python Solution
def restore_ip_addresses(s):
result = []
def is_valid(segment):
if not segment or len(segment) > 3:
return False
if len(segment) > 1 and segment[0] == '0':
return False
return 0 <= int(segment) <= 255
BY: coding_error1
if len(segments) >= 4 or index >= len(s):
return
backtrack(0, [])
return result
# Example usage
print(restore_ip_addresses("25525511135"))
Java Solution
import java.util.*;
C++ Solution
BY: coding_error1
#include <vector>
#include <string>
using namespace std;
class RestoreIPAddresses {
public:
vector<string> restoreIpAddresses(string s) {
vector<string> result;
vector<string> segments;
backtrack(s, 0, segments, result);
return result;
}
private:
void backtrack(string& s, int index, vector<string>& segments,
vector<string>& result) {
if (segments.size() == 4) {
if (index == s.length()) {
result.push_back(join(segments));
}
return;
}
Python Solution
def word_break(s, word_dict):
word_set = set(word_dict)
BY: coding_error1
result = []
backtrack(0, [])
return result
# Example usage
s = "catsanddog"
word_dict = ["cat", "cats", "and", "sand", "dog"]
print(word_break(s, word_dict))
Java Solution
import java.util.*;
C++ Solution
#include <vector>
#include <string>
#include <unordered_set>
using namespace std;
BY: coding_error1
class WordBreakII {
public:
vector<string> wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
vector<string> result;
vector<string> currentSentence;
backtrack(s, 0, currentSentence, wordSet, result);
return result;
}
private:
void backtrack(string& s, int index, vector<string>& currentSentence,
unordered_set<string>& wordSet, vector<string>& result)
{
if (index == s.length()) {
result.push_back(join(currentSentence));
return;
}
BY: coding_error1