Backtracking
Backtracking
Backtracking
1 Introduction 5
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
4 Rat in a Maze 25
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5 N Queen Problem 34
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
8 8 queen problem 53
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
9 Subset Sum 54
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
10 m Coloring Problem 61
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
11 Hamiltonian Cycle 69
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
12 Sudoku 80
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
1
Contents
14 Magnet Puzzle 91
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
22 Minimum queens required to cover all the squares of a chess board 129
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
25 Smallest number with given sum of digits and sum of square of digits 142
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
2
Contents
34 Print all possible strings that can be made by placing spaces 198
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
3
Contents
51 Print all possible paths from top left to bottom right of a mXn matrix 276
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
53 Given an array A[] and a number x, check for pair in A[] with sum as x 287
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
4
Chapter 1
Introduction
• Recursion
• Complexity Analysis
5
Chapter 1. Introduction
coin. This is what backtracking is, that is solving all sub-problems one by one in order to
reach the best possible solution.
Consider the below example to understand the Backtracking approach more formally,
The Algorithm begins to build up a solution, starting with an empty solution set . S=
{}
1. Add to the first move that is still left (All possible moves are added to one by
one). This now creates a new sub-tree in the search tree of the algorithm.
using argument .
4. If the check for returns that it is a solution for the entire data . Output
and terminate the program.
If not, then return that no solution is possible with the current and hence discard
it.
6
Chapter 1. Introduction
The expected output is a binary matrix which has 1s for the blocks where queens are placed.
For example, following is the output matrix for the above 4 queen solution.
{ 0, 1, 0, 0}
{ 0, 0, 0, 1}
{ 1, 0, 0, 0}
{ 0, 0, 1, 0}
Backtracking Algorithm: The idea is to place queens one by one in different columns,
starting from the leftmost column. When we place a queen in a column, we check for clashes
7
Chapter 1. Introduction
with already placed queens. In the current column, if we find a row for which there is no
clash, we mark this row and column as part of the solution. If we do not find such a row
due to clashes then we backtrack and return false.
You may refer to the article on Backtracking | Set 3 (N Queen Problem) for complete
implementation of the above approach.
More Backtracking Problems:
Source
https://www.geeksforgeeks.org/backtracking-introduction/
8
Chapter 2
Let us first discuss the Naive algorithm for this problem and then the Backtracking algo-
rithm.
9
Chapter 2. The Knight’s tour problem
Following are implementations for Knight’s tour problem. It prints one of the possible
solutions in 2D matrix form. Basically, the output is a 2D 8*8 matrix with numbers from
0 to 63 and these numbers show steps made by Knight.
10
Chapter 2. The Knight’s tour problem
11
Chapter 2. The Knight’s tour problem
12
Chapter 2. The Knight’s tour problem
return 0;
}
Java
13
Chapter 2. The Knight’s tour problem
14
Chapter 2. The Knight’s tour problem
C#
// C# program for
// Knight Tour problem
using System;
class GFG
{
static int N = 8;
/* A utility function to
check if i,j are valid
indexes for N*N chessboard */
static bool isSafe(int x, int y,
int[,] sol)
{
return (x >= 0 && x < N &&
y >= 0 && y < N &&
sol[x, y] == -1);
}
/* A utility function to
print solution matrix sol[N][N] */
static void printSolution(int[,] sol)
{
for (int x = 0; x < N; x++)
{
for (int y = 0; y < N; y++)
Console.Write(sol[x, y] + " ");
Console.WriteLine();
}
}
/* This function solves the
Knight Tour problem using
Backtracking. This function
mainly uses solveKTUtil() to
solve the problem. It returns
false if no complete tour is
possible, otherwise return true
and prints the tour. Please note
that there may be more than one
solutions, this function prints
one of the feasible solutions. */
static bool solveKT()
{
int[,] sol = new int[8, 8];
15
Chapter 2. The Knight’s tour problem
/* Initialization of
solution matrix */
for (int x = 0; x < N; x++)
for (int y = 0; y < N; y++)
sol[x, y] = -1;
/* xMove[] and yMove[] define
next move of Knight.
xMove[] is for next
value of x coordinate
yMove[] is for next
value of y coordinate */
int[] xMove = {2, 1, -1, -2,
-2, -1, 1, 2};
int[] yMove = {1, 2, 2, 1,
-1, -2, -2, -1};
// Since the Knight is
// initially at the first block
sol[0, 0] = 0;
/* Start from 0,0 and explore
all tours using solveKTUtil() */
if (!solveKTUtil(0, 0, 1, sol,
xMove, yMove))
{
Console.WriteLine("Solution does "+
"not exist");
return false;
}
else
printSolution(sol);
return true;
}
/* A recursive utility function
to solve Knight Tour problem */
static bool solveKTUtil(int x, int y, int movei,
int[,] sol, int[] xMove,
int[] yMove)
{
int k, next_x, next_y;
if (movei == N * N)
return true;
/* Try all next moves from
the current coordinate x, y */
16
Chapter 2. The Knight’s tour problem
Output:
0 59 38 33 30 17 8 63
37 34 31 60 9 62 29 16
58 1 36 39 32 27 18 7
35 48 41 26 61 10 15 28
42 57 2 49 40 23 6 19
47 50 45 54 25 20 11 14
56 43 52 3 22 13 24 5
51 46 55 44 53 4 21 12
Note that Backtracking is not the best solution for the Knight’s tour problem. See below
article for other better solutions. The purpose of this post is to explain Backtracking with
an example.
Warnsdorff’s algorithm for Knight’s tour problem
References:
http://see.stanford.edu/materials/icspacs106b/H19-RecBacktrackExamples.pdf
http://www.cis.upenn.edu/~matuszek/cit594-2009/Lectures/35-backtracking.ppt
17
Chapter 2. The Knight’s tour problem
http://mathworld.wolfram.com/KnightsTour.html
http://en.wikipedia.org/wiki/Knight%27s_tour
Improved By : Mithun Kumar
Source
https://www.geeksforgeeks.org/the-knights-tour-problem-backtracking-1/
18
Chapter 3
We have discussed Backtracking Algorithm for solution of Knight’s tour. In this post Warns-
dorff’s heuristic is discussed.
Warnsdorff’s Rule:
1. We can start from any initial position of the knight on the board.
2. We always move to an adjacent, unvisited square with minimal degree (minimum
number of unvisited adjacent).
19
Chapter 3. Warnsdorff’s algorithm for Knight’s tour problem
Algorithm:
20
Chapter 3. Warnsdorff’s algorithm for Knight’s tour problem
21
Chapter 3. Warnsdorff’s algorithm for Knight’s tour problem
return true;
}
/* displays the chessboard with all the
legal knight's moves */
void print(int a[])
{
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < N; ++j)
printf("%d\t",a[j*N+i]);
printf("\n");
}
}
/* checks its neighbouring sqaures */
/* If the knight ends on a square that is one
knight's move from the beginning square,
then tour is closed */
bool neighbour(int x, int y, int xx, int yy)
{
for (int i = 0; i < N; ++i)
if (((x+cx[i]) == xx)&&((y + cy[i]) == yy))
return true;
return false;
}
/* Generates the legal moves using warnsdorff's
heuristics. Returns false if not possible */
bool findClosedTour()
{
// Filling up the chessboard matrix with -1's
int a[N*N];
for (int i = 0; i< N*N; ++i)
a[i] = -1;
// Randome initial position
int sx = rand()%N;
int sy = rand()%N;
// Current points are same as initial points
int x = sx, y = sy;
a[y*N+x] = 1; // Mark first move.
// Keep picking next points using
// Warnsdorff's heuristic
22
Chapter 3. Warnsdorff’s algorithm for Knight’s tour problem
Output:
59 14 63 32 1 16 19 34
62 31 60 15 56 33 2 17
13 58 55 64 49 18 35 20
30 61 42 57 54 51 40 3
43 12 53 50 41 48 21 36
26 29 44 47 52 39 4 7
11 46 27 24 9 6 37 22
28 25 10 45 38 23 8 5
23
Chapter 3. Warnsdorff’s algorithm for Knight’s tour problem
tours along the same path that travel in opposite directions are counted separately, as are
rotations and reflections). The number of undirected closed tours is half this number, since
every tour can be traced in reverse!”
Source
https://www.geeksforgeeks.org/warnsdorffs-algorithm-knights-tour-problem/
24
Chapter 4
Rat in a Maze
{1, 0, 0, 0}
25
Chapter 4. Rat in a Maze
{1, 1, 0, 1}
{0, 1, 0, 0}
{1, 1, 1, 1}
Following is the solution matrix (output of program) for the above input matrx.
{1, 0, 0, 0}
{1, 1, 0, 0}
{0, 1, 0, 0}
{0, 1, 1, 1}
All enteries in solution path are marked as 1.
Naive Algorithm
The Naive Algorithm is to generate all paths from source to destination and one by one
check if the generated path satisfies the constraints.
Backtracking Algorithm
If destination is reached
print the solution matrix
Else
a) Mark current cell in solution matrix as 1.
b) Move forward in the horizontal direction and recursively check if this
move leads to a solution.
26
Chapter 4. Rat in a Maze
C/C++
27
Chapter 4. Rat in a Maze
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
};
if(solveMazeUtil(maze, 0, 0, sol) == false)
{
printf("Solution doesn't exist");
return false;
}
printSolution(sol);
return true;
}
/* A recursive utility function to solve Maze problem */
bool solveMazeUtil(int maze[N][N], int x, int y, int sol[N][N])
{
// if (x,y is goal) return true
if(x == N-1 && y == N-1)
{
sol[x][y] = 1;
return true;
}
// Check if maze[x][y] is valid
if(isSafe(maze, x, y) == true)
{
// mark x,y as part of solution path
sol[x][y] = 1;
/* Move forward in x direction */
if (solveMazeUtil(maze, x+1, y, sol) == true)
return true;
/* If moving in x direction doesn't give solution then
Move down in y direction */
if (solveMazeUtil(maze, x, y+1, sol) == true)
return true;
/* If none of the above movements work then BACKTRACK:
unmark x,y as part of solution path */
sol[x][y] = 0;
return false;
}
return false;
}
28
Chapter 4. Rat in a Maze
// driver program to test above function
int main()
{
int maze[N][N] = { {1, 0, 0, 0},
{1, 1, 0, 1},
{0, 1, 0, 0},
{1, 1, 1, 1}
};
solveMaze(maze);
return 0;
}
Java
29
Chapter 4. Rat in a Maze
30
Chapter 4. Rat in a Maze
/* If none of the above movements works then
BACKTRACK: unmark x,y as part of solution
path */
sol[x][y] = 0;
return false;
}
return false;
}
public static void main(String args[])
{
RatMaze rat = new RatMaze();
int maze[][] = {{1, 0, 0, 0},
{1, 1, 0, 1},
{0, 1, 0, 0},
{1, 1, 1, 1}
};
rat.solveMaze(maze);
}
}
// This code is contributed by Abhishek Shankhadhar
Python3
31
Chapter 4. Rat in a Maze
""" This function solves the Maze problem using Backtracking.
It mainly uses solveMazeUtil() to solve the problem. It
returns false if no path is possible, otherwise return
true and prints the path in the form of 1s. Please note
that there may be more than one solutions, this function
prints one of the feasable solutions. """
def solveMaze( maze ):
# Creating a 4 * 4 2-D list
sol = [ [ 0 for j in range(4) ] for i in range(4) ]
if solveMazeUtil(maze, 0, 0, sol) == False:
print("Solution doesn't exist");
return False
printSolution(sol)
return True
# A recursive utility function to solve Maze problem
def solveMazeUtil(maze, x, y, sol):
#if (x,y is goal) return True
if x == N - 1 and y == N - 1:
sol[x][y] = 1
return True
# Check if maze[x][y] is valid
if isSafe(maze, x, y) == True:
# mark x, y as part of solution path
sol[x][y] = 1
# Move forward in x direction
if solveMazeUtil(maze, x + 1, y, sol) == True:
return True
# If moving in x direction doesn't give solution
# then Move down in y direction
if solveMazeUtil(maze, x, y + 1, sol) == True:
return True
# If none of the above movements work then
# BACKTRACK: unmark x,y as part of solution path
sol[x][y] = 0
return False
# Driver program to test above function
if __name__ == "__main__":
32
Chapter 4. Rat in a Maze
1 0 0 0
1 1 0 0
0 1 0 0
0 1 1 1
Source
https://www.geeksforgeeks.org/rat-in-a-maze-backtracking-2/
33
Chapter 5
N Queen Problem
The expected output is a binary matrix which has 1s for the blocks where queens are placed.
For example, following is the output matrix for above 4 queen solution.
{ 0, 1, 0, 0}
34
Chapter 5. N Queen Problem
{ 0, 0, 0, 1}
{ 1, 0, 0, 0}
{ 0, 0, 1, 0}
Naive Algorithm
Generate all possible configurations of queens on board and print a configuration that sat-
isfies the given constraints.
Backtracking Algorithm
The idea is to place queens one by one in different columns, starting from the leftmost
column. When we place a queen in a column, we check for clashes with already placed
queens. In the current column, if we find a row for which there is no clash, we mark this
row and column as part of the solution. If we do not find such a row due to clashes then we
backtrack and return false.
C/C++
35
Chapter 5. N Queen Problem
/* A utility function to print solution */
void printSolution(int board[N][N])
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
printf(" %d ", board[i][j]);
printf("\n");
}
}
/* A utility function to check if a queen can
be placed on board[row][col]. Note that this
function is called when "col" queens are
already placed in columns from 0 to col -1.
So we need to check only left side for
attacking queens */
bool isSafe(int board[N][N], int row, int col)
{
int i, j;
/* Check this row on left side */
for (i = 0; i < col; i++)
if (board[row][i])
return false;
/* Check upper diagonal on left side */
for (i=row, j=col; i>=0 && j>=0; i--, j--)
if (board[i][j])
return false;
/* Check lower diagonal on left side */
for (i=row, j=col; j>=0 && i<N; i++, j--)
if (board[i][j])
return false;
return true;
}
/* A recursive utility function to solve N
Queen problem */
bool solveNQUtil(int board[N][N], int col)
{
/* base case: If all queens are placed
then return true */
if (col >= N)
return true;
36
Chapter 5. N Queen Problem
/* Consider this column and try placing
this queen in all rows one by one */
for (int i = 0; i < N; i++)
{
/* Check if the queen can be placed on
board[i][col] */
if ( isSafe(board, i, col) )
{
/* Place this queen in board[i][col] */
board[i][col] = 1;
/* recur to place rest of the queens */
if ( solveNQUtil(board, col + 1) )
return true;
/* If placing queen in board[i][col]
doesn't lead to a solution, then
remove queen from board[i][col] */
board[i][col] = 0; // BACKTRACK
}
}
/* If the queen cannot be placed in any row in
this colum col then return false */
return false;
}
/* This function solves the N Queen problem using
Backtracking. It mainly uses solveNQUtil() to
solve the problem. It returns false if queens
cannot be placed, otherwise, return true and
prints placement of queens in the form of 1s.
Please note that there may be more than one
solutions, this function prints one of the
feasible solutions.*/
bool solveNQ()
{
int board[N][N] = { {0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
};
if ( solveNQUtil(board, 0) == false )
{
printf("Solution does not exist");
return false;
37
Chapter 5. N Queen Problem
}
printSolution(board);
return true;
}
// driver program to test above function
int main()
{
solveNQ();
return 0;
}
Java
38
Chapter 5. N Queen Problem
39
Chapter 5. N Queen Problem
Python
40
Chapter 5. N Queen Problem
# A utility function to check if a queen can
# be placed on board[row][col]. Note that this
# function is called when "col" queens are
# already placed in columns from 0 to col -1.
# So we need to check only left side for
# attacking queens
def isSafe(board, row, col):
# Check this row on left side
for i in range(col):
if board[row][i] == 1:
return False
# Check upper diagonal on left side
for i,j in zip(range(row,-1,-1), range(col,-1,-1)):
if board[i][j] == 1:
return False
# Check lower diagonal on left side
for i,j in zip(range(row,N,1), range(col,-1,-1)):
if board[i][j] == 1:
return False
return True
def solveNQUtil(board, col):
# base case: If all queens are placed
# then return true
if col >= N:
return True
# Consider this column and try placing
# this queen in all rows one by one
for i in range(N):
if isSafe(board, i, col):
# Place this queen in board[i][col]
board[i][col] = 1
# recur to place rest of the queens
if solveNQUtil(board, col+1) == True:
return True
# If placing queen in board[i][col
# doesn't lead to a solution, then
# queen from board[i][col]
41
Chapter 5. N Queen Problem
board[i][col] = 0
# if the queen can not be placed in any row in
# this colum col then return false
return False
# This function solves the N Queen problem using
# Backtracking. It mainly uses solveNQUtil() to
# solve the problem. It returns false if queens
# cannot be placed, otherwise return true and
# placement of queens in the form of 1s.
# note that there may be more than one
# solutions, this function prints one of the
# feasible solutions.
def solveNQ():
board = [ [0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
]
if solveNQUtil(board, 0) == False:
print "Solution does not exist"
return False
printSolution(board)
return True
# driver program to test above function
solveNQ()
# This code is contributed by Divyanshu Mehta
0 0 1 0
1 0 0 0
0 0 0 1
0 1 0 0
42
Chapter 5. N Queen Problem
Source
https://www.geeksforgeeks.org/n-queen-problem-backtracking-3/
43
Chapter 6
Place(k, i)
// Returns true if a queen can be placed
// in kth row and ith column. Otherwise it
// returns false. X[] is a global array
// whose first (k-1) values have been set.
// Abs( ) returns absolute value of r
{
for j := 1 to k-1 do
return true;
}
Algorithm nQueens(k, n) :
44
Chapter 6. N Queen in O(n) space
C++
45
Chapter 6. N Queen in O(n) space
Output:
---------------------------------
Arrangement No. 1
---------------------------------
_ Q _ _
_ _ _ Q
Q _ _ _
_ _ Q _
---------------------------------
---------------------------------
Arrangement No. 2
46
Chapter 6. N Queen in O(n) space
---------------------------------
_ _ Q _
Q _ _ _
_ _ _ Q
_ Q _ _
---------------------------------
Source
https://www.geeksforgeeks.org/n-queen-in-on-space/
47
Chapter 7
48
Chapter 7. Printing all solutions in N-Queen Problem
In previous post, we have discussed an approach that prints only one possible solution, so
now in this post the task is to print all solutions in N-Queen Problem. The solution discussed
here is an extension of same approach.
Backtracking Algorithm
The idea is to place queens one by one in different columns, starting from the leftmost
column. When we place a queen in a column, we check for clashes with already placed
queens. In the current column, if we find a row for which there is no clash, we mark this
row and column as part of the solution. If we do not find such a row due to clashes then we
backtrack and return false.
There is only a slight modification in above algorithm that is highlighted in the code.
49
Chapter 7. Printing all solutions in N-Queen Problem
backtracking */
#include<bits/stdc++.h>
#define N 4
/* A utility function to print solution */
void printSolution(int board[N][N])
{
static int k = 1;
printf("%d-\n",k++);
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
printf(" %d ", board[i][j]);
printf("\n");
}
printf("\n");
}
/* A utility function to check if a queen can
be placed on board[row][col]. Note that this
function is called when "col" queens are
already placed in columns from 0 to col -1.
So we need to check only left side for
attacking queens */
bool isSafe(int board[N][N], int row, int col)
{
int i, j;
/* Check this row on left side */
for (i = 0; i < col; i++)
if (board[row][i])
return false;
/* Check upper diagonal on left side */
for (i=row, j=col; i>=0 && j>=0; i--, j--)
if (board[i][j])
return false;
/* Check lower diagonal on left side */
for (i=row, j=col; j>=0 && i<N; i++, j--)
if (board[i][j])
return false;
return true;
}
/* A recursive utility function to solve N
Queen problem */
50
Chapter 7. Printing all solutions in N-Queen Problem
51
Chapter 7. Printing all solutions in N-Queen Problem
int board[N][N];
memset(board, 0, sizeof(board));
if (solveNQUtil(board, 0) == false)
{
printf("Solution does not exist");
return ;
}
return ;
}
// driver program to test above function
int main()
{
solveNQ();
return 0;
}
Output:
1-
0 0 1 0
1 0 0 0
0 0 0 1
0 1 0 0
2-
0 1 0 0
0 0 0 1
1 0 0 0
0 0 1 0
Source
https://www.geeksforgeeks.org/printing-solutions-n-queen-problem/
52
Chapter 8
8 queen problem
Source
https://www.geeksforgeeks.org/8-queen-problem/
53
Chapter 9
Subset Sum
54
Chapter 9. Subset Sum
In the above tree, a node represents function call and a branch represents candidate element.
The root node contains 4 children. In other words, root considers every element of the set as
different branch. The next level sub-trees correspond to the subsets that includes the parent
node. The branches at each level represent tuple element to be considered. For example, if
we are at level 1, tuple_vector[1] can take any value of four branches generated. If we are
at level 2 of left most node, tuple_vector[2] can take any value of three branches generated,
and so on…
For example the left most child of root generates all those subsets that include w[1]. Similarly
the second child of root generates all those subsets that includes w[2] and excludes w[1].
As we go down along depth of tree we add elements so far, and if the added sum is satis-
fying explicit constraints, we will continue to generate child nodes further. Whenever the
constraints are not met, we stop further generation of sub-trees of that node, and back-
track to previous node to explore the nodes not yet explored. In many scenarios, it saves
considerable amount of processing time.
The tree should trigger a clue to implement the backtracking algorithm (try yourself). It
prints all those subsets whose sum add up to given number. We need to explore the nodes
along the breadth and depth of the tree. Generating nodes along breadth is controlled by
loop and nodes along the depth are generated using recursion (post order traversal). Pseudo
code given below,
55
Chapter 9. Subset Sum
Following is C implementation of subset sum using variable size tuple vector. Note that the
following program explores all possibilities similar to exhaustive search. It is to demonstrate
how backtracking can be used. See next code to verify, how we can optimize the backtracking
solution.
#include <stdio.h>
#include <stdlib.h>
#define ARRAYSIZE(a) (sizeof(a))/(sizeof(a[0]))
static int total_nodes;
// prints subset found
void printSubset(int A[], int size)
{
for(int i = 0; i < size; i++)
{
printf("%*d", 5, A[i]);
}
printf("n");
}
// inputs
// s - set vector
// t - tuplet vector
// s_size - set size
// t_size - tuplet size so far
// sum - sum so far
// ite - nodes count
// target_sum - sum to be found
void subset_sum(int s[], int t[],
int s_size, int t_size,
int sum, int ite,
int const target_sum)
{
total_nodes++;
if( target_sum == sum )
{
// We found subset
printSubset(t, t_size);
// Exclude previously added item and consider next candidate
subset_sum(s, t, s_size, t_size-1, sum - s[ite], ite + 1, target_sum);
return;
}
else
{
// generate nodes along the breadth
for( int i = ite; i < s_size; i++ )
56
Chapter 9. Subset Sum
{
t[t_size] = s[i];
// consider next level node (along depth)
subset_sum(s, t, s_size, t_size + 1, sum + s[i], i + 1, target_sum);
}
}
}
// Wrapper to print subsets that sum to target_sum
// input is weights vector and target_sum
void generateSubsets(int s[], int size, int target_sum)
{
int *tuplet_vector = (int *)malloc(size * sizeof(int));
subset_sum(s, tuplet_vector, size, 0, 0, 0, target_sum);
free(tuplet_vector);
}
int main()
{
int weights[] = {10, 7, 5, 18, 12, 20, 15};
int size = ARRAYSIZE(weights);
generateSubsets(weights, size, 35);
printf("Nodes generated %dn", total_nodes);
return 0;
}
The power of backtracking appears when we combine explicit and implicit constraints, and
we stop generating nodes when these checks fail. We can improve the above algorithm by
strengthening the constraint checks and presorting the data. By sorting the initial array,
we need not to consider rest of the array, once the sum so far is greater than target number.
We can backtrack and check other possibilities.
Similarly, assume the array is presorted and we found one subset. We can generate next node
excluding the present node only when inclusion of next node satisfies the constraints. Given
below is optimized implementation (it prunes the subtree if it is not satisfying contraints).
#include <stdio.h>
#include <stdlib.h>
#define ARRAYSIZE(a) (sizeof(a))/(sizeof(a[0]))
static int total_nodes;
// prints subset found
void printSubset(int A[], int size)
57
Chapter 9. Subset Sum
{
for(int i = 0; i < size; i++)
{
printf("%*d", 5, A[i]);
}
printf("n");
}
// qsort compare function
int comparator(const void *pLhs, const void *pRhs)
{
int *lhs = (int *)pLhs;
int *rhs = (int *)pRhs;
return *lhs > *rhs;
}
// inputs
// s - set vector
// t - tuplet vector
// s_size - set size
// t_size - tuplet size so far
// sum - sum so far
// ite - nodes count
// target_sum - sum to be found
void subset_sum(int s[], int t[],
int s_size, int t_size,
int sum, int ite,
int const target_sum)
{
total_nodes++;
if( target_sum == sum )
{
// We found sum
printSubset(t, t_size);
// constraint check
if( ite + 1 < s_size && sum - s[ite] + s[ite+1] <= target_sum )
{
// Exclude previous added item and consider next candidate
subset_sum(s, t, s_size, t_size-1, sum - s[ite], ite + 1, target_sum);
}
return;
}
else
{
58
Chapter 9. Subset Sum
59
Chapter 9. Subset Sum
As another approach, we can generate the tree in fixed size tuple analogs to binary pattern.
We will kill the sub-trees when the constraints are not satisfied.
– – – Venki. Please write comments if you find anything incorrect, or you want to share
more information about the topic discussed above.
Source
https://www.geeksforgeeks.org/subset-sum-backtracking-4/
60
Chapter 10
m Coloring Problem
Naive Algorithm
Generate all possible configurations of colors and print a configuration that satisfies the
given constraints.
61
Chapter 10. m Coloring Problem
C/C++
#include<stdio.h>
// Number of vertices in the graph
#define V 4
void printSolution(int color[]);
/* A utility function to check if the current color assignment
is safe for vertex v i.e. checks whether the edge exists or not
(i.e, graph[v][i]==1). If exist then checks whether the color to
be filled in the new vertex(c is sent in the parameter) is already
used by its adjacent vertices(i-->adj vertices) or not (i.e, color[i]==c) */
bool isSafe (int v, bool graph[V][V], int color[], int c)
{
for (int i = 0; i < V; i++)
if (graph[v][i] && c == color[i])
return false;
return true;
}
/* A recursive utility function to solve m coloring problem */
bool graphColoringUtil(bool graph[V][V], int m, int color[], int v)
{
/* base case: If all vertices are assigned a color then
return true */
62
Chapter 10. m Coloring Problem
if (v == V)
return true;
/* Consider this vertex v and try different colors */
for (int c = 1; c <= m; c++)
{
/* Check if assignment of color c to v is fine*/
if (isSafe(v, graph, color, c))
{
color[v] = c;
/* recur to assign colors to rest of the vertices */
if (graphColoringUtil (graph, m, color, v+1) == true)
return true;
/* If assigning color c doesn't lead to a solution
then remove it */
color[v] = 0;
}
}
/* If no color can be assigned to this vertex then return false */
return false;
}
/* This function solves the m Coloring problem using Backtracking.
It mainly uses graphColoringUtil() to solve the problem. It returns
false if the m colors cannot be assigned, otherwise return true and
prints assignments of colors to all vertices. Please note that there
may be more than one solutions, this function prints one of the
feasible solutions.*/
bool graphColoring(bool graph[V][V], int m)
{
// Initialize all color values as 0. This initialization is needed
// correct functioning of isSafe()
int *color = new int[V];
for (int i = 0; i < V; i++)
color[i] = 0;
// Call graphColoringUtil() for vertex 0
if (graphColoringUtil(graph, m, color, 0) == false)
{
printf("Solution does not exist");
return false;
}
// Print the solution
printSolution(color);
63
Chapter 10. m Coloring Problem
return true;
}
/* A utility function to print solution */
void printSolution(int color[])
{
printf("Solution Exists:"
" Following are the assigned colors \n");
for (int i = 0; i < V; i++)
printf(" %d ", color[i]);
printf("\n");
}
// driver program to test above function
int main()
{
/* Create following graph and test whether it is 3 colorable
(3)---(2)
| / |
| / |
| / |
(0)---(1)
*/
bool graph[V][V] = {{0, 1, 1, 1},
{1, 0, 1, 0},
{1, 1, 0, 1},
{1, 0, 1, 0},
};
int m = 3; // Number of colors
graphColoring (graph, m);
return 0;
}
Java
64
Chapter 10. m Coloring Problem
return false;
return true;
}
/* A recursive utility function to solve m
coloring problem */
boolean graphColoringUtil(int graph[][], int m,
int color[], int v)
{
/* base case: If all vertices are assigned
a color then return true */
if (v == V)
return true;
/* Consider this vertex v and try different
colors */
for (int c = 1; c <= m; c++)
{
/* Check if assignment of color c to v
is fine*/
if (isSafe(v, graph, color, c))
{
color[v] = c;
/* recur to assign colors to rest
of the vertices */
if (graphColoringUtil(graph, m,
color, v + 1))
return true;
/* If assigning color c doesn't lead
to a solution then remove it */
color[v] = 0;
}
}
/* If no color can be assigned to this vertex
then return false */
return false;
}
/* This function solves the m Coloring problem using
Backtracking. It mainly uses graphColoringUtil()
to solve the problem. It returns false if the m
colors cannot be assigned, otherwise return true
and prints assignments of colors to all vertices.
Please note that there may be more than one
solutions, this function prints one of the
65
Chapter 10. m Coloring Problem
feasible solutions.*/
boolean graphColoring(int graph[][], int m)
{
// Initialize all color values as 0. This
// initialization is needed correct functioning
// of isSafe()
color = new int[V];
for (int i = 0; i < V; i++)
color[i] = 0;
// Call graphColoringUtil() for vertex 0
if (!graphColoringUtil(graph, m, color, 0))
{
System.out.println("Solution does not exist");
return false;
}
// Print the solution
printSolution(color);
return true;
}
/* A utility function to print solution */
void printSolution(int color[])
{
System.out.println("Solution Exists: Following" +
" are the assigned colors");
for (int i = 0; i < V; i++)
System.out.print(" " + color[i] + " ");
System.out.println();
}
// driver program to test above function
public static void main(String args[])
{
mColoringProblem Coloring = new mColoringProblem();
/* Create following graph and test whether it is
3 colorable
(3)---(2)
| / |
| / |
| / |
(0)---(1)
*/
int graph[][] = {{0, 1, 1, 1},
{1, 0, 1, 0},
{1, 1, 0, 1},
{1, 0, 1, 0},
66
Chapter 10. m Coloring Problem
};
int m = 3; // Number of colors
Coloring.graphColoring(graph, m);
}
}
// This code is contributed by Abhishek Shankhadhar
Python
67
Chapter 10. m Coloring Problem
print c,
return True
# Driver Code
g = Graph(4)
g.graph = [[0,1,1,1], [1,0,1,0], [1,1,0,1], [1,0,1,0]]
m=3
g.graphColouring(m)
# This code is contributed by Divyanshu Mehta
Output:
References:
http://en.wikipedia.org/wiki/Graph_coloring
Improved By : SarathChandra1
Source
https://www.geeksforgeeks.org/m-coloring-problem-backtracking-5/
68
Chapter 11
Hamiltonian Cycle
(0)--(1)--(2)
| / \ |
| / \ |
| / \ |
(3)-------(4)
(0)--(1)--(2)
| / \ |
69
Chapter 11. Hamiltonian Cycle
| / \ |
| / \ |
(3) (4)
Naive Algorithm
Generate all possible configurations of vertices and print a configuration that satisfies the
given constraints. There will be n! (n factorial) configurations.
Backtracking Algorithm
Create an empty path array and add vertex 0 to it. Add other vertices, starting from the
vertex 1. Before adding a vertex, check for whether it is adjacent to the previously added
vertex and not already added. If we find such a vertex, we add the vertex as part of the
solution. If we do not find a vertex then we return false.
Implementation of Backtracking solution
Following are implementations of the Backtracking solution.
C/C++
70
Chapter 11. Hamiltonian Cycle
71
Chapter 11. Hamiltonian Cycle
}
/* This function solves the Hamiltonian Cycle problem using Backtracking.
It mainly uses hamCycleUtil() to solve the problem. It returns false
if there is no Hamiltonian Cycle possible, otherwise return true and
prints the path. Please note that there may be more than one solutions,
this function prints one of the feasible solutions. */
bool hamCycle(bool graph[V][V])
{
int *path = new int[V];
for (int i = 0; i < V; i++)
path[i] = -1;
/* Let us put vertex 0 as the first vertex in the path. If there is
a Hamiltonian Cycle, then the path can be started from any point
of the cycle as the graph is undirected */
path[0] = 0;
if ( hamCycleUtil(graph, path, 1) == false )
{
printf("\nSolution does not exist");
return false;
}
printSolution(path);
return true;
}
/* A utility function to print solution */
void printSolution(int path[])
{
printf ("Solution Exists:"
" Following is one Hamiltonian Cycle \n");
for (int i = 0; i < V; i++)
printf(" %d ", path[i]);
// Let us print the first vertex again to show the complete cycle
printf(" %d ", path[0]);
printf("\n");
}
// driver program to test above function
int main()
{
/* Let us create the following graph
(0)--(1)--(2)
| / \ |
| / \ |
| / \ |
72
Chapter 11. Hamiltonian Cycle
(3)-------(4) */
bool graph1[V][V] = {{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},
};
// Print the solution
hamCycle(graph1);
/* Let us create the following graph
(0)--(1)--(2)
| / \ |
| / \ |
| / \ |
(3) (4) */
bool graph2[V][V] = {{0, 1, 0, 1, 0},
{1, 0, 1, 1, 1},
{0, 1, 0, 0, 1},
{1, 1, 0, 0, 0},
{0, 1, 1, 0, 0},
};
// Print the solution
hamCycle(graph2);
return 0;
}
Java
73
Chapter 11. Hamiltonian Cycle
/* Check if the vertex has already been included.
This step can be optimized by creating an array
of size V */
for (int i = 0; i < pos; i++)
if (path[i] == v)
return false;
return true;
}
/* A recursive utility function to solve hamiltonian
cycle problem */
boolean hamCycleUtil(int graph[][], int path[], int pos)
{
/* base case: If all vertices are included in
Hamiltonian Cycle */
if (pos == V)
{
// And if there is an edge from the last included
// vertex to the first vertex
if (graph[path[pos - 1]][path[0]] == 1)
return true;
else
return false;
}
// Try different vertices as a next candidate in
// Hamiltonian Cycle. We don't try for 0 as we
// included 0 as starting point in in hamCycle()
for (int v = 1; v < V; v++)
{
/* Check if this vertex can be added to Hamiltonian
Cycle */
if (isSafe(v, graph, path, pos))
{
path[pos] = v;
/* recur to construct rest of the path */
if (hamCycleUtil(graph, path, pos + 1) == true)
return true;
/* If adding vertex v doesn't lead to a solution,
then remove it */
path[pos] = -1;
}
}
74
Chapter 11. Hamiltonian Cycle
75
Chapter 11. Hamiltonian Cycle
HamiltonianCycle hamiltonian =
new HamiltonianCycle();
/* Let us create the following graph
(0)--(1)--(2)
| / \ |
| / \ |
| / \ |
(3)-------(4) */
int graph1[][] = {{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},
};
// Print the solution
hamiltonian.hamCycle(graph1);
/* Let us create the following graph
(0)--(1)--(2)
| / \ |
| / \ |
| / \ |
(3) (4) */
int graph2[][] = {{0, 1, 0, 1, 0},
{1, 0, 1, 1, 1},
{0, 1, 0, 0, 1},
{1, 1, 0, 0, 0},
{0, 1, 1, 0, 0},
};
// Print the solution
hamiltonian.hamCycle(graph2);
}
}
// This code is contributed by Abhishek Shankhadhar
Python
76
Chapter 11. Hamiltonian Cycle
77
Chapter 11. Hamiltonian Cycle
def hamCycle(self):
path = [-1] * self.V
''' Let us put vertex 0 as the first vertex
in the path. If there is a Hamiltonian Cycle,
then the path can be started from any point
of the cycle as the graph is undirected '''
path[0] = 0
if self.hamCycleUtil(path,1) == False:
print "Solution does not exist\n"
return False
self.printSolution(path)
return True
def printSolution(self, path):
print "Solution Exists: Following is one Hamiltonian Cycle"
for vertex in path:
print vertex,
print path[0], "\n"
# Driver Code
''' Let us create the following graph
(0)--(1)--(2)
| / \ |
| / \ |
| / \ |
(3)-------(4) '''
g1 = Graph(5)
g1.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], ]
# Print the solution
g1.hamCycle();
''' Let us create the following graph
(0)--(1)--(2)
| / \ |
| / \ |
| / \ |
(3) (4) '''
g2 = Graph(5)
g2.graph = [ [0, 1, 0, 1, 0], [1, 0, 1, 1, 1],
[0, 1, 0, 0, 1,], [1, 1, 0, 0, 0],
[0, 1, 1, 0, 0], ]
78
Chapter 11. Hamiltonian Cycle
# Print the solution
g2.hamCycle();
# This code is contributed by Divyanshu Mehta
Output:
Note that the above code always prints cycle starting from 0. Starting point should not
matter as cycle can be started from any point. If you want to change the starting point,
you should make two changes to above code.
Change “path[0] = 0;” to “path[0] = s;” where s is your new starting point. Also change
loop “for (int v = 1; v < V; v++)” in hamCycleUtil() to ”for (int v = 0; v < V; v++)”.
Please write comments if you find anything incorrect, or you want to share more information
about the topic discussed above.
Source
https://www.geeksforgeeks.org/hamiltonian-cycle-backtracking-6/
79
Chapter 12
Sudoku
Naive Algorithm
The Naive Algorithm is to generate all possible configurations of numbers from 1 to 9 to fill
the empty cells. Try every configuration one by one until the correct configuration is found.
Backtracking Algorithm
Like all other Backtracking problems, we can solve Sudoku by one by one assigning numbers
to empty cells. Before assigning a number, we check whether it is safe to assign. We basically
check that the same number is not present in the current row, current column and current
3X3 subgrid. After checking for safety, we assign the number, and recursively check whether
this assignment leads to a solution or not. If the assignment doesn’t lead to a solution, then
80
Chapter 12. Sudoku
we try next number for the current empty cell. And if none of the number (1 to 9) leads to
a solution, we return false.
Following are C++ and Python implementation for Sudoku problem. It prints the
completely filled grid as output.
C/C++
81
Chapter 12. Sudoku
82
Chapter 12. Sudoku
}
/* Returns a boolean which indicates whether an assigned entry
within the specified 3x3 box matches the given number. */
bool UsedInBox(int grid[N][N], int boxStartRow, int boxStartCol, int num)
{
for (int row = 0; row < 3; row++)
for (int col = 0; col < 3; col++)
if (grid[row+boxStartRow][col+boxStartCol] == num)
return true;
return false;
}
/* Returns a boolean which indicates whether it will be legal to assign
num to the given row,col location. */
bool isSafe(int grid[N][N], int row, int col, int num)
{
/* Check if 'num' is not already placed in current row,
current column and current 3x3 box */
return !UsedInRow(grid, row, num) &&
!UsedInCol(grid, col, num) &&
!UsedInBox(grid, row - row%3 , col - col%3, num);
}
/* A utility function to print grid */
void printGrid(int grid[N][N])
{
for (int row = 0; row < N; row++)
{
for (int col = 0; col < N; col++)
printf("%2d", grid[row][col]);
printf("\n");
}
}
/* Driver Program to test above functions */
int main()
{
// 0 means unassigned cells
int grid[N][N] = {{3, 0, 6, 5, 0, 8, 4, 0, 0},
{5, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 8, 7, 0, 0, 0, 0, 3, 1},
{0, 0, 3, 0, 1, 0, 0, 8, 0},
{9, 0, 0, 8, 6, 3, 0, 0, 5},
{0, 5, 0, 0, 9, 0, 6, 0, 0},
{1, 3, 0, 0, 0, 0, 2, 5, 0},
{0, 0, 0, 0, 0, 0, 0, 7, 4},
{0, 0, 5, 2, 0, 6, 3, 0, 0}};
83
Chapter 12. Sudoku
Python
84
Chapter 12. Sudoku
for i in range(9):
if(arr[i][col] == num):
return True
return False
# Returns a boolean which indicates whether any assigned entry
# within the specified 3x3 box matches the given number
def used_in_box(arr,row,col,num):
for i in range(3):
for j in range(3):
if(arr[i+row][j+col] == num):
return True
return False
# Checks whether it will be legal to assign num to the given row,col
# Returns a boolean which indicates whether it will be legal to assign
# num to the given row,col location.
def check_location_is_safe(arr,row,col,num):
# Check if 'num' is not already placed in current row,
# current column and current 3x3 box
return not used_in_row(arr,row,num) and not used_in_col(arr,col,num) and not used_in_box(arr,
# Takes a partially filled-in grid and attempts to assign values to
# all unassigned locations in such a way to meet the requirements
# for Sudoku solution (non-duplication across rows, columns, and boxes)
def solve_sudoku(arr):
# 'l' is a list variable that keeps the record of row and col in find_empty_location Function
l=[0,0]
# If there is no unassigned location, we are done
if(not find_empty_location(arr,l)):
return True
# Assigning list values to row and col that we got from the above Function
row=l[0]
col=l[1]
# consider digits 1 to 9
for num in range(1,10):
# if looks promising
if(check_location_is_safe(arr,row,col,num)):
# make tentative assignment
arr[row][col]=num
85
Chapter 12. Sudoku
Output:
3 1 6 5 7 8 4 9 2
5 2 9 1 3 4 7 6 8
4 8 7 6 2 9 5 3 1
2 6 3 4 1 5 9 8 7
9 7 4 8 6 3 1 2 5
8 5 1 7 9 2 6 4 3
1 3 8 9 4 7 2 5 6
6 9 2 3 5 1 8 7 4
7 4 5 2 8 6 3 1 9
86
Chapter 12. Sudoku
References:
http://see.stanford.edu/materials/icspacs106b/H19-RecBacktrackExamples.pdf
Source
https://www.geeksforgeeks.org/sudoku-backtracking-7/
87
Chapter 13
SEND
+ MORE
--------
MONEY
--------
The goal here is to assign each letter a digit from 0 to 9 so that the arithmetic works out
correctly. The rules are that all occurrences of a letter must be assigned the same digit, and
no digit can be assigned to more than one letter.
• First, create a list of all the characters that need assigning to pass to Solve
• If all characters are assigned, return true if puzzle is solved, false otherwise
• Otherwise, consider the first unassigned character
• for (every possible choice among the digits not in use)
• If all digits have been tried and nothing worked, return false to trigger backtracking
/* ExhaustiveSolve
* ---------------
* This is the "not-very-smart" version of cryptarithmetic solver. It takes
* the puzzle itself (with the 3 strings for the two addends and sum) and a
* string of letters as yet unassigned. If no more letters to assign
* then we've hit a base-case, if the current letter-to-digit mapping solves
* the puzzle, we're done, otherwise we return false to trigger backtracking
* If we have letters to assign, we take the first letter from that list, and
* try assigning it the digits from 0 to 9 and then recursively working
* through solving puzzle from here. If we manage to make a good assignment
88
Chapter 13. Solving Cryptarithmetic Puzzles
* that works, we've succeeded, else we need to unassign that choice and try
* another digit. This version is easy to write, since it uses a simple
* approach (quite similar to permutations if you think about it) but it is
* not so smart because it doesn't take into account the structure of the
* puzzle constraints (for example, once the two digits for the addends have
* been assigned, there is no reason to try anything other than the correct
* digit for the sum) yet it tries a lot of useless combos regardless
*/
bool ExhaustiveSolve(puzzleT puzzle, string lettersToAssign)
{
if (lettersToAssign.empty()) // no more choices to make
return PuzzleSolved(puzzle); // checks arithmetic to see if works
for (int digit = 0; digit <= 9; digit++) // try all digits
{
if (AssignLetterToDigit(lettersToAssign[0], digit))
{
if (ExhaustiveSolve(puzzle, lettersToAssign.substr(1)))
return true;
UnassignLetterFromDigit(lettersToAssign[0], digit);
}
}
return false; // nothing worked, need to backtrack
}
The algorithm above actually has a lot in common with the permutations algorithm, it
pretty much just creates all arrangements of the mapping from characters to digits and tries
each until one works or all have been successfully tried. For a large puzzle, this could take
a while.
A smarter algorithm could take into account the structure of the puzzle and avoid going
down dead-end paths. For example, if we assign the characters starting from the ones place
and moving to the left, at each stage, we can verify the correctness of what we have so far
before we continue onwards. This definitely complicates the code but leads to a tremendous
improvement in efficiency, making it much more feasible to solve large puzzles.
Below pseudocode in this case has more special cases, but the same general design
• Start by examining the rightmost digit of the topmost row, with a carry of 0
• If we are beyond the leftmost digit of the puzzle, return true if no carry, false otherwise
• If we are currently trying to assign a char in one of the addends
If char already assigned, just recur on row beneath this one, adding value into sum
If not assigned, then
– for (every possible choice among the digits not in use)
make that choice and then on row beneath this one, if successful, return true
if !successful, unmake assignment and try another digit
– return false if no assignment worked to trigger backtracking
• Else if trying to assign a char in the sum
• If char assigned & matches correct,
recur on next column to the left with carry, if success return true,
89
Chapter 13. Solving Cryptarithmetic Puzzles
Source:
http://see.stanford.edu/materials/icspacs106b/H19-RecBacktrackExamples.pdf
Source
https://www.geeksforgeeks.org/solving-cryptarithmetic-puzzles-backtracking-8/
90
Chapter 14
Magnet Puzzle
Each slot contains either a blank entry (indicated by ‘x’s), or a “magnet” with a positive
and negative end. The numbers along the left and top sides show the numbers of ‘+’ squares
in particular rows or columns. Those along the right and bottom show the number of ‘-’
signs in particular rows or columns. Rows and columns without a number at one or both
ends are unconstrained as to the number of ‘+’ or ‘-’ signs, depending on which number is
not present. In addition to fulfilling these numerical constraints, a puzzle solution must also
satisfy the constraint that no two orthogonally touching squares may have the same sign
(diagonally joined squares are not constrained).
You are given top[], bottom[], left[], right[] arrays indicates the count of + or – along the
top(+), bottom(-), left(+) and right(-) edges respectively. Values of -1 indicate any number
of + and – signs. Also given matrix rules[][] contain any one T, B, L or R characters. For
a vertical slot in the board, T indicates its top end and B indicates the bottom end. For a
horizontal slot in the board, L indicates left end and R indicates the right end.
Examples:
91
Chapter 14. Magnet Puzzle
Input : M = 5, N = 6
top[] = { 1, -1, -1, 2, 1, -1 }
bottom[] = { 2, -1, -1, 2, -1, 3 }
left[] = { 2, 3, -1, -1, -1 }
right[] = { -1, -1, -1, 1, -1 }
rules[][] = { { L, R, L, R, T, T },
{ L, R, L, R, B, B },
{ T, T, T, T, L, R },
{ B, B, B, B, T, T },
{ L, R, L, R, B, B }};
Output : + - + - X -
- + - + X +
X X + - + -
X X - + X +
- + X X X -
Input : M = 4, N = 3
top[] = { 2, -1, -1 }
bottom[] = { -1, -1, 2 }
left[] = { -1, -1, 2, -1 }
right[] = { 0, -1, -1, -1 }
rules[][] = { { T, T, T },
{ B, B, B },
{ T, L, R },
{ B, L, R } };
Output : + X +
– X –
+ – +
– + –
Source
https://www.geeksforgeeks.org/magnet-puzzle-backtracking-9/
92
Chapter 15
93
Chapter 15. Boggle | Set 1 (Using DFS)
The idea is to consider every character as a starting character and find all words starting
with it. All words starting from a character can be found using Depth First Traversal. We
do depth first traversal starting from every cell. We keep track of visited cells to make sure
that a cell is considered only once in a word.
94
Chapter 15. Boggle | Set 1 (Using DFS)
95
Chapter 15. Boggle | Set 1 (Using DFS)
Output:
Note that the above solution may print the same word multiple times. For example, if
we add “SEEK” to the dictionary, it is printed multiple times. To avoid this, we can use
hashing to keep track of all printed words.
In below set 2, we have discussed Trie based optimized solution:
Boggle | Set 2 (Using Trie)
This article is contributed by Rishabh. Please write comments if you find anything incor-
rect, or you want to share more information about the topic discussed above.
Source
https://www.geeksforgeeks.org/boggle-find-possible-words-board-characters/
96
Chapter 16
97
Chapter 16. Boggle | Set 2 (Using Trie)
2. After that we have pick only those character in boggle[][] which are child of root of Trie
Let for above we pick ‘G’ boggle[0][0] , ‘Q’ boggle[2][0] (they both are present in boggle
matrix)
3. search a word in a trie which start with character that we pick in step 2
98
Chapter 16. Boggle | Set 2 (Using Trie)
if root->leaf == true
print word
C++
99
Chapter 16. Boggle | Set 2 (Using Trie)
100
Chapter 16. Boggle | Set 2 (Using Trie)
{
// make it visited
visited[i][j] = true;
// traverse all childs of current root
for (int K =0; K < SIZE; K++)
{
if (root->Child[K] != NULL)
{
// current character
char ch = (char)K + (char)'A' ;
// Recursively search reaming character of word
// in trie for all 8 adjacent cells of boggle[i][j]
if (isSafe(i+1,j+1,visited) && boggle[i+1][j+1] == ch)
searchWord(root->Child[K],boggle,i+1,j+1,visited,str+ch);
if (isSafe(i, j+1,visited) && boggle[i][j+1] == ch)
searchWord(root->Child[K],boggle,i, j+1,visited,str+ch);
if (isSafe(i-1,j+1,visited) && boggle[i-1][j+1] == ch)
searchWord(root->Child[K],boggle,i-1, j+1,visited,str+ch);
if (isSafe(i+1,j, visited) && boggle[i+1][j] == ch)
searchWord(root->Child[K],boggle,i+1, j,visited,str+ch);
if (isSafe(i+1,j-1,visited) && boggle[i+1][j-1] == ch)
searchWord(root->Child[K],boggle,i+1, j-1,visited,str+ch);
if (isSafe(i, j-1,visited)&& boggle[i][j-1] == ch)
searchWord(root->Child[K],boggle,i,j-1,visited,str+ch);
if (isSafe(i-1,j-1,visited) && boggle[i-1][j-1] == ch)
searchWord(root->Child[K],boggle,i-1, j-1,visited,str+ch);
if (isSafe(i-1, j,visited) && boggle[i-1][j] == ch)
searchWord(root->Child[K],boggle,i-1, j, visited,str+ch);
}
}
// make current element unvisited
visited[i][j] = false;
}
}
// Prints all words present in dictionary.
void findWords(char boggle[M][N], TrieNode *root)
{
// Mark all characters as not visited
bool visited[M][N];
memset(visited,false,sizeof(visited));
TrieNode *pChild = root ;
string str = "";
101
Chapter 16. Boggle | Set 2 (Using Trie)
// traverse all matrix elements
for (int i = 0 ; i < M; i++)
{
for (int j = 0 ; j < N ; j++)
{
// we start searching for word in dictionary
// if we found a character which is child
// of Trie root
if (pChild->Child[char_int(boggle[i][j])] )
{
str = str+boggle[i][j];
searchWord(pChild->Child[char_int(boggle[i][j])],
boggle, i, j, visited, str);
str = "";
}
}
}
}
//Driver program to test above function
int main()
{
// Let the given dictionary be following
char *dictionary[] = {"GEEKS", "FOR", "QUIZ", "GEE"};
// root Node of trie
TrieNode *root = getNode();
// insert all words of dictionary into trie
int n = sizeof(dictionary)/sizeof(dictionary[0]);
for (int i=0; i<n; i++)
insert(root, dictionary[i]);
char boggle[M][N] = {{'G','I','Z'},
{'U','E','K'},
{'Q','S','E'}
};
findWords(boggle, root);
return 0;
}
Java
102
Chapter 16. Boggle | Set 2 (Using Trie)
// Alphabet size
static final int SIZE = 26;
static final int M = 3;
static final int N = 3;
// trie Node
static class TrieNode
{
TrieNode[] Child = new TrieNode[SIZE];
// isLeaf is true if the node represents
// end of a word
boolean leaf;
//constructor
public TrieNode() {
leaf = false;
for (int i =0 ; i< SIZE ; i++)
Child[i] = null;
}
}
// If not present, inserts a key into the trie
// If the key is a prefix of trie node, just
// marks leaf node
static void insert(TrieNode root, String Key)
{
int n = Key.length();
TrieNode pChild = root;
for (int i=0; i<n; i++)
{
int index = Key.charAt(i) - 'A';
if (pChild.Child[index] == null)
pChild.Child[index] = new TrieNode();
pChild = pChild.Child[index];
}
// make last node as leaf node
pChild.leaf = true;
}
// function to check that current location
// (i and j) is in matrix range
103
Chapter 16. Boggle | Set 2 (Using Trie)
104
Chapter 16. Boggle | Set 2 (Using Trie)
105
Chapter 16. Boggle | Set 2 (Using Trie)
}
}
}
// Driver program to test above function
public static void main(String args[])
{
// Let the given dictionary be following
String dictionary[] = {"GEEKS", "FOR", "QUIZ", "GEE"};
// root Node of trie
TrieNode root = new TrieNode();
// insert all words of dictionary into trie
int n = dictionary.length;
for (int i=0; i<n; i++)
insert(root, dictionary[i]);
char boggle[][] = {{'G','I','Z'},
{'U','E','K'},
{'Q','S','E'}
};
findWords(boggle, root);
}
}
// This code is contributed by Sumit Ghosh
Output:
Source
https://www.geeksforgeeks.org/boggle-set-2-using-trie/
106
Chapter 17
Tug of War
C++
#include <iostream>
#include <stdlib.h>
#include <limits.h>
using namespace std;
// function that tries every possible solution by calling itself recursively
void TOWUtil(int* arr, int n, bool* curr_elements, int no_of_selected_elements,
107
Chapter 17. Tug of War
bool* soln, int* min_diff, int sum, int curr_sum, int curr_position)
{
// checks whether the it is going out of bound
if (curr_position == n)
return;
// checks that the numbers of elements left are not less than the
// number of elements required to form the solution
if ((n/2 - no_of_selected_elements) > (n - curr_position))
return;
// consider the cases when current element is not included in the solution
TOWUtil(arr, n, curr_elements, no_of_selected_elements,
soln, min_diff, sum, curr_sum, curr_position+1);
// add the current element to the solution
no_of_selected_elements++;
curr_sum = curr_sum + arr[curr_position];
curr_elements[curr_position] = true;
// checks if a solution is formed
if (no_of_selected_elements == n/2)
{
// checks if the solution formed is better than the best solution so far
if (abs(sum/2 - curr_sum) < *min_diff)
{
*min_diff = abs(sum/2 - curr_sum);
for (int i = 0; i<n; i++)
soln[i] = curr_elements[i];
}
}
else
{
// consider the cases where current element is included in the solution
TOWUtil(arr, n, curr_elements, no_of_selected_elements, soln,
min_diff, sum, curr_sum, curr_position+1);
}
// removes current element before returning to the caller of this function
curr_elements[curr_position] = false;
}
// main function that generate an arr
void tugOfWar(int *arr, int n)
{
// the boolen array that contains the inclusion and exclusion of an element
// in current set. The number excluded automatically form the other set
bool* curr_elements = new bool[n];
108
Chapter 17. Tug of War
// The inclusion/exclusion array for final solution
bool* soln = new bool[n];
int min_diff = INT_MAX;
int sum = 0;
for (int i=0; i<n; i++)
{
sum += arr[i];
curr_elements[i] = soln[i] = false;
}
// Find the solution using recursive function TOWUtil()
TOWUtil(arr, n, curr_elements, 0, soln, &min_diff, sum, 0, 0);
// Print the solution
cout << "The first subset is: ";
for (int i=0; i<n; i++)
{
if (soln[i] == true)
cout << arr[i] << " ";
}
cout << "\nThe second subset is: ";
for (int i=0; i<n; i++)
{
if (soln[i] == false)
cout << arr[i] << " ";
}
}
// Driver program to test above functions
int main()
{
int arr[] = {23, 45, -34, 12, 0, 98, -99, 4, 189, -1, 4};
int n = sizeof(arr)/sizeof(arr[0]);
tugOfWar(arr, n);
return 0;
}
Java
109
Chapter 17. Tug of War
{
public int min_diff;
// function that tries every possible solution
// by calling itself recursively
void TOWUtil(int arr[], int n, boolean curr_elements[],
int no_of_selected_elements, boolean soln[],
int sum, int curr_sum, int curr_position)
{
// checks whether the it is going out of bound
if (curr_position == n)
return;
// checks that the numbers of elements left
// are not less than the number of elements
// required to form the solution
if ((n / 2 - no_of_selected_elements) >
(n - curr_position))
return;
// consider the cases when current element
// is not included in the solution
TOWUtil(arr, n, curr_elements,
no_of_selected_elements, soln, sum,
curr_sum, curr_position+1);
// add the current element to the solution
no_of_selected_elements++;
curr_sum = curr_sum + arr[curr_position];
curr_elements[curr_position] = true;
// checks if a solution is formed
if (no_of_selected_elements == n / 2)
{
// checks if the solution formed is
// better than the best solution so
// far
if (Math.abs(sum / 2 - curr_sum) <
min_diff)
{
min_diff = Math.abs(sum / 2 -
curr_sum);
for (int i = 0; i < n; i++)
soln[i] = curr_elements[i];
}
}
else
{
110
Chapter 17. Tug of War
111
Chapter 17. Tug of War
Output:
This article is compiled by Ashish Anand and reviewed by GeeksforGeeks team. Please
write comments if you find anything incorrect, or you want to share more information about
the topic discussed above.
Source
https://www.geeksforgeeks.org/tug-of-war/
112
Chapter 18
Input : 1 2 3
Output : // this space denotes null element.
1
1 2
1 2 3
1 3
2
2 3
3
Input : 1 2
Output :
1
2
1 2
We have already discussed iterative approach to find all subsets. This article aims to provide
a backtracking approach.
Idea is that if we have n number of elements inside an array, we have exactly two choices
for each of the elements. Either we include that element in our subset or we do not include
it.
113
Chapter 18. Backtracking to find all subsets
// In the array A at every step we have two
// choices for each element either we can
// ignore the element or we can include the
// element in our subset
void subsetsUtil(vector<int>& A, vector<vector<int> >& res,
vector<int>& subset, int index)
{
for (int i = index; i < A.size(); i++) {
// include the A[i] in subset.
subset.push_back(A[i]);
res.push_back(subset);
// move onto the next element.
subsetsUtil(A, res, subset, i + 1);
// exclude the A[i] from subset and triggers
// backtracking.
subset.pop_back();
}
return;
}
// below function returns the subsets of vector A.
vector<vector<int> > subsets(vector<int>& A)
{
vector<int> subset;
vector<vector<int> > res;
// include the null element in the set.
res.push_back(subset);
// keeps track of current element in vector A;
int index = 0;
subsetsUtil(A, res, subset, index);
return res;
}
// Driver Code.
int main()
{
// find the subsets of below vector.
vector<int> array = { 1, 2, 3 };
// res will store all subsets.
114
Chapter 18. Backtracking to find all subsets
Output:
1
1 2
1 2 3
1 3
2
2 3
3
Source
https://www.geeksforgeeks.org/backtracking-to-find-all-subsets/
115
Chapter 19
116
Chapter 19. Print the DFS traversal step-wise (Backtracking also)
Note: In this above diagram the weight between the edges has just been added, it does not
have any role in DFS-traversal
Approach: DFS with Backtracking will be used here. First, visit every node using DFS
simultaneously and keep track of the previously used edge and the parent node. If a node
comes whose all the adjacent node has been visited, backtrack using the last used edge and
print the nodes. Continue the steps and at every step, the parent node will become the
present node. Continue the above steps to find the complete DFS traversal of the graph.
Below is the implementation of the above approach:
117
Chapter 19. Print the DFS traversal step-wise (Backtracking also)
118
Chapter 19. Print the DFS traversal step-wise (Backtracking also)
visited[i] = false;
// call the function
dfsUtil(0, node, visited, road_used, -1, 0);
}
// Function to insert edges in Graph
void insertEdge(int u, int v)
{
adj[u].push_back(v);
adj[v].push_back(u);
}
// Driver Code
int main()
{
// number of nodes and edges in the graph
int node = 11, edge = 13;
// Function call to create the graph
insertEdge(0, 1);
insertEdge(0, 2);
insertEdge(1, 5);
insertEdge(1, 6);
insertEdge(2, 4);
insertEdge(2, 9);
insertEdge(6, 7);
insertEdge(6, 8);
insertEdge(7, 8);
insertEdge(2, 3);
insertEdge(3, 9);
insertEdge(3, 10);
insertEdge(9, 10);
// Call the function to print
dfs(node);
return 0;
}
Output:
0 1 5 1 6 7 8 7 6 1 0 2 4 2 9 3 10
Source
https://www.geeksforgeeks.org/print-the-dfs-traversal-step-wise-backtracking-also/
119
Chapter 20
120
Chapter 20. C++ program for Solving Cryptarithmetic Puzzles
121
Chapter 20. C++ program for Solving Cryptarithmetic Puzzles
{
char ch = s3[i];
for (j = 0; j < count; j++)
if (nodeArr[j].c == ch)
break;
val3 += m * nodeArr[j].v;
m *= 10;
}
// sum of first two number equal to third return true
if (val3 == (val1 + val2))
return 1;
// else return false
return 0;
}
// Recursive function to check solution for all permutations
bool permutation(const int count, node* nodeArr, int n,
string s1, string s2, string s3)
{
// Base case
if (n == count - 1)
{
// check for all numbers not used yet
for (int i = 0; i < 10; i++)
{
// if not used
if (use[i] == 0)
{
// assign char at index n integer i
nodeArr[n].v = i;
// if solution found
if (check(nodeArr, count, s1, s2, s3) == 1)
{
cout << "\nSolution found: ";
for (int j = 0; j < count; j++)
cout << " " << nodeArr[j].c << " = "
<< nodeArr[j].v;
return true;
}
}
}
122
Chapter 20. C++ program for Solving Cryptarithmetic Puzzles
return false;
}
for (int i = 0; i < 10; i++)
{
// if ith integer not used yet
if (use[i] == 0)
{
// assign char at index n integer i
nodeArr[n].v = i;
// mark it as not available for other char
use[i] = 1;
// call recursive function
if (permutation(count, nodeArr, n + 1, s1, s2, s3))
return true;
// backtrack for all other possible solutions
use[i] = 0;
}
}
return false;
}
bool solveCryptographic(string s1, string s2,
string s3)
{
// count to store number of unique char
int count = 0;
// Length of all three strings
int l1 = s1.length();
int l2 = s2.length();
int l3 = s3.length();
// vector to store frequency of each char
vector<int> freq(26);
for (int i = 0; i < l1; i++)
++freq[s1[i] - 'A'];
for (int i = 0; i < l2; i++)
++freq[s2[i] - 'A'];
for (int i = 0; i < l3; i++)
123
Chapter 20. C++ program for Solving Cryptarithmetic Puzzles
++freq[s3[i] - 'A'];
// count number of unique char
for (int i = 0; i < 26; i++)
if (freq[i] > 0)
count++;
// solution not possible for count greater than 10
if (count > 10)
{
cout << "Invalid strings";
return 0;
}
// array of nodes
node nodeArr[count];
// store all unique char in nodeArr
for (int i = 0, j = 0; i < 26; i++)
{
if (freq[i] > 0)
{
nodeArr[j].c = char(i + 'A');
j++;
}
}
return permutation(count, nodeArr, 0, s1, s2, s3);
}
// Driver function
int main()
{
string s1 = "SEND";
string s2 = "MORE";
string s3 = "MONEY";
if (solveCryptographic(s1, s2, s3) == false)
cout << "No solution";
return 0;
}
Output:
Solution found: D=1 E=5 M=0 N=3 O=8 R=2 S=7 Y=6
124
Chapter 20. C++ program for Solving Cryptarithmetic Puzzles
Source
https://www.geeksforgeeks.org/c-code-article-backtracking-set-8-solving-cryptarithmetic-puzzles/
125
Chapter 21
A backtracking approach to
generate n bit Gray Codes
Input : 2
Output : 0 1 3 2
Explanation :
00 - 0
01 - 1
11 - 3
10 - 2
Input : 3
Output : 0 1 3 2 6 7 5 4
126
Chapter 21. A backtracking approach to generate n bit Gray Codes
/* we have 2 choices for each of the n bits either we
can include i.e invert the bit or we can exclude the
bit i.e we can leave the number as it is. */
void grayCodeUtil(vector<int>& res, int n, int& num)
{
// base case when we run out bits to process
// we simply include it in gray code sequence.
if (n == 0) {
res.push_back(num);
return;
}
// ignore the bit.
grayCodeUtil(res, n - 1, num);
// invert the bit.
num = num ^ (1 << (n - 1));
grayCodeUtil(res, n - 1, num);
}
// returns the vector containing the gray
// code sequence of n bits.
vector<int> grayCodes(int n)
{
vector<int> res;
// num is passed by reference to keep
// track of current code.
int num = 0;
grayCodeUtil(res, n, num);
return res;
}
// Driver function.
int main()
{
int n = 3;
vector<int> code = grayCodes(n);
for (int i = 0; i < code.size(); i++)
cout << code[i] << endl;
return 0;
}
Output:
127
Chapter 21. A backtracking approach to generate n bit Gray Codes
0
1
3
2
6
7
5
4
Source
https://www.geeksforgeeks.org/backtracking-approach-generate-n-bit-gray-codes/
128
Chapter 22
Minimum queens required to cover all the squares of a chess board - GeeksforGeeks
Given the dimension of a chess board (N x M), determine the minimum number of queens
required to cover all the squares of the board. A queen can attack any square along its row,
column or diagonals.
Examples:
Input : N = 8, M = 8
Output : 5
Layout : Q X X X X X X X
X X Q X X X X X
X X X X Q X X X
X Q X X X X X X
X X X Q X X X X
X X X X X X X X
X X X X X X X X
X X X X X X X X
Input : N = 3, M = 5
Output : 2
Layout : Q X X X X
X X X X X
X X X Q X
This article attempts to solve the problem in a very simple way without much optimization.
129
Chapter 22. Minimum queens required to cover all the squares of a chess board
Step 1: Starting from any corner square of the board, find an ‘uncovered’ square
(Uncovered square is a square which isn’t attacked by any of the queens already
placed). If none found, goto Step 4.
Step 2: Place a Queen on this square and increment variable ‘count’ by 1.
Step 3: Repeat step 1.
Step 4: Now, you’ve got a layout where every square is covered. Therefore, the
value of ‘count’ can be the answer. However, you might be able to do better, as
there might exist a better layout with lesser number of queens. So, store this
‘count’ as the best value till now and proceed to find a better solution.
Step 5: Remove the last queen placed and place it in the next ‘uncovered’ cell.
Step 6: Proceed recursively and try out all the possible layouts. Finally, the one
with the least number of queens is the answer.
130
Chapter 22. Minimum queens required to cover all the squares of a chess board
if (countSoFar >= minCount)
// We've already obtained a solution with lesser or
// same number of queens. Hence, no need to proceed.
return;
// Checks if there exists any unattacked cells.
findUnattackedCell : {
for (i = 0; i < N; ++i)
for (j = 0; j < M; ++j)
if (!isAttacked(i, j))
// Square (i, j) is unattacked.
break findUnattackedCell;
// All squares all covered. Hence, this
// is the best solution till now.
minCount = countSoFar;
storeLayout();
return;
}
for (i = 0; i < N; ++i)
for (j = 0; j < M; ++j) {
if (!isAttacked(i, j)) {
// Square (i, j) is unattacked.
// Therefore, place a queen here.
board[i][j] = true;
// Increment 'count' and proceed recursively.
placeQueen(countSoFar + 1);
// Remove this queen and attempt to
// find a better solution.
board[i][j] = false;
}
}
}
// Returns 'true' if the square (row, col) is
// being attacked by at least one queen.
static boolean isAttacked(int row, int col)
{
int i, j;
131
Chapter 22. Minimum queens required to cover all the squares of a chess board
Output:
132
Chapter 22. Minimum queens required to cover all the squares of a chess board
Layout:
Q X X X X X X X
X X Q X X X X X
X X X X Q X X X
X Q X X X X X X
X X X Q X X X X
X X X X X X X X
X X X X X X X X
X X X X X X X X
Improved By : sarthakmannaofficial
Source
https://www.geeksforgeeks.org/minimum-queens-required-to-cover-all-the-squares-of-a-chess-board/
133
Chapter 23
Input: ED
Output:
D
DE
E
134
Chapter 23. Print all the combinations of a string in lexicographical order
ED
Approach: Count the occurrences of all the characters in the string using a map, then
using recursion all the possible combinations can be printed. Store the elements and their
counts in two different arrays. Three arrays are used, input[] array which has the characters,
count[] array has the count of characters and result[] is a temporary array which is used
in recursion to generate all the combinations. Using recursion and backtracking all the
combinations can be printed.
Below is the implementation of the above approach.
135
Chapter 23. Print all the combinations of a string in lexicographical order
// call the function from level +1
stringCombination(result, str, count,
level + 1, size, length);
// backtracking
count[i]++;
}
}
void combination(string str)
{
// declare the map for store
// each char with occurrence
map<char, int> mp;
for (int i = 0; i < str.size(); i++) {
if (mp.find(str[i]) != mp.end())
mp[str[i]] = mp[str[i]] + 1;
else
mp[str[i]] = 1;
}
// initialize the input array
// with all unique char
char* input = new char[mp.size()];
// initialize the count array with
// occurrence the unique char
int* count = new int[mp.size()];
// temporary char array for store the result
char* result = new char[str.size()];
map<char, int>::iterator it = mp.begin();
int i = 0;
for (it; it != mp.end(); it++) {
// store the element of input array
input[i] = it->first;
// store the element of count array
count[i] = it->second;
i++;
}
136
Chapter 23. Print all the combinations of a string in lexicographical order
Output:
A
AB
ABC
AC
ACB
B
BA
BAC
BC
BCA
C
CA
CAB
CB
CBA
Source
https://www.geeksforgeeks.org/print-all-the-combinations-of-a-string-in-lexicographical-order/
137
Chapter 24
Method 1 : The idea is to fix a prefix, general all subsets beginning with current prefix.
After all subsets with a prefix are generated, replace last character with one of the remaining
characters.
138
Chapter 24. Recursive program to generate power set
// base case
if (index == n)
return;
// First print current subset
cout << curr << "\n";
// Try appending remaining characters
// to current subset
for (int i = index + 1; i < n; i++) {
curr += str[i];
powerSet(str, i, curr);
// Once all subsets beginning with
// initial "curr" are printed, remove
// last character to consider a different
// prefix of subsets.
curr.erase(curr.size() - 1);
}
return;
}
// Driver code
int main()
{
string str = "abc";
powerSet(str);
return 0;
}
Output:
a
ab
abc
ac
b
bc
c
Method 2 : The idea is to consider two cases for every character. (i) Consider current
character as part of current subset (ii) Do not consider current character as part of current
subset.
139
Chapter 24. Recursive program to generate power set
Output:
abc
ab
ac
a
bc
b
c
140
Chapter 24. Recursive program to generate power set
Source
https://www.geeksforgeeks.org/recursive-program-to-generate-power-set/
141
Chapter 25
Smallest number with given sum of digits and sum of square of digits - GeeksforGeeks
Given sum of digits and sum of square of digits . Find the smallest number with given
sum of digits and sum of the square of digits. The number should not contain more than
100 digits. Print -1 if no such number exists or if the number of digits is more than 100.
Examples:
Approach:
Since the smallest number can be of 100 digits, it cannot be stored. Hence the first step to
solve it will be to find the minimum number of digits which can give us the sum of digits
as and sum of the square of digits as . To find the minimum number of digits, we can
use Dynamic Programming. DP[a][b] signifies the minimum number of digits in a number
whose sum of the digits will be and sum of the square of digits will be . If there does
not exist any such number then DP[a][b] will be -1.
Since the number cannot exceed 100 digits, DP array will be of size 101*8101. Iterate for
every digit, and try all possible combination of digits which gives us the sum of digits as
and sum of the square of digits as . Store the minimum number of digits in DP[a][b] using
the below recurrence relation:
142
Chapter 25. Smallest number with given sum of digits and sum of square of digits
After getting the minimum number of digits, find the digits. To find the digits, check for all
combinations and print those digits which satisfies the condition below:
If the condition above is met by any of i, reduce by i and by i*i and break. Keep on
repeating the above process to find all the digits till is 0 and is 0.
Below is the C++ implementation of above approach:
143
Chapter 25. Smallest number with given sum of digits and sum of square of digits
// If the combination of digits cannot give sum as a
// and sum of square of digits as b
if (k != -1)
ans = min(ans, k + 1);
}
// Returns the minimum number of digits
return dp[a][b] = ans;
}
// Function to print the digits that gives
// sum as a and sum of square of digits as b
void printSmallestNumber(int a,int b)
{
// initialize the dp array as -1
memset(dp, -1, sizeof(dp));
// base condition
dp[0][0] = 0;
// function call to get the minimum number of digits
int k = minimumNumberOfDigits(a, b);
// When there does not exists any number
if (k == -1 || k > 100)
cout << "-1";
else {
// Printing the digits from the most significant digit
while (a > 0 && b > 0) {
// Trying all combinations
for (int i = 1; i <= 9; i++) {
// checking conditions for minimum digits
if (a >= i && b >= i * i &&
1 + dp[a - i][b - i * i] == dp[a][b]) {
cout << i;
a -= i;
b -= i * i;
break;
}
}
}
}
}
// Driver Code
144
Chapter 25. Smallest number with given sum of digits and sum of square of digits
int main()
{
int a = 18, b = 162;
// Function call to print the smallest number
printSmallestNumber(a,b);
}
Output:
99
Source
https://www.geeksforgeeks.org/smallest-number-with-given-sum-of-digits-and-sum-of-square-of-digits/
145
Chapter 26
Input : A = ababa
B = babab
Output : 1
Swapping all b's in string A, with
a's in string B results in string
A having all characters as a.
Input : A = abaaa
B = bbabb
Output : 2
Initially string A has 2 unique
characters. Swapping at any index
does not change this count.
Approach: The problem can be solved using backtracking. Create a map in which key is
A[i] and value is count of corresponding character. The size of the map tells the number of
distinct characters as only those elements which are present in string A are present as key
in map. At every index position, there are two choices: either swap A[i] with B[i] or keep
A[i] unchanged. Start from index 0 and do following for each index:
146
Chapter 26. Minimize number of unique characters in string
1. Keep A[i] unchanged, increment count of A[i] by one in map and call recursively for
next index.
2. Backtrack by decreasing count of A[i] by one, swap A[i] with B[i], increment count of
A[i] by one in map and again recursively call for next index.
Keep a variable ans to store overall minimum value of distinct characters. In both the
cases mentioned above, when entire string is traversed compare current number of distinct
characters with overall minimum in ans and update ans accordingly.
Implementation:
147
Chapter 26. Minimize number of unique characters in string
// Restore A to original form.
// (Backtracking step)
swap(A[ind], B[ind]);
// Increase count of A[i] in map and
// call recursively for next index.
ele[A[ind]]++;
minCountUtil(A, B, ele, ans, ind + 1);
// Restore the changes done
// (Backtracking step)
ele[A[ind]]--;
if (ele[A[ind]] == 0)
ele.erase(A[ind]);
}
// Function to find minimum number of
// distinct characters in string.
int minCount(string A, string B)
{
// Variable to store minimum number
// of distinct character.
// Initialize it with length of A
// as maximum possible value is
// length of A.
int ans = A.length();
// Map to store count of distinct
// characters in A. To keep
// complexity of insert operation
// constant unordered_map is used.
unordered_map<char, int> ele;
// Call utility function to find
// minimum number of unique
// characters.
minCountUtil(A, B, ele, ans, 0);
return ans;
}
int main()
{
string A = "abaaa";
string B = "bbabb";
cout << minCount(A, B);
148
Chapter 26. Minimize number of unique characters in string
return 0;
}
Output:
Source
https://www.geeksforgeeks.org/minimize-number-unique-characters-string/
149
Chapter 27
Explanation
Rat started with M[0][0] and can jump upto 2 steps right/down.
150
Chapter 27. Rat in a Maze with multiple steps or jump allowed
Input : {
{2, 1, 0, 0},
{2, 0, 0, 1},
{0, 1, 0, 1},
{0, 0, 0, 1}
}
Output : Solution doesn't exist
Naive Algorithm
The Naive Algorithm is to generate all paths from source to destination and one by one
check if the generated path satisfies the constraints.
Backtracking Algorithm
If destination is reached
print the solution matrix
Else
a) Mark current cell in solution matrix as 1.
b) Move forward/jump (for each valid steps) in horizontal direction
and recursively check if this move leads to a solution.
c) If the move chosen in the above step doesn't lead to a solution
then move down and check if this move leads to a solution.
d) If none of the above solutions work then unmark this cell as 0
(BACKTRACK) and return false.
151
Chapter 27. Rat in a Maze with multiple steps or jump allowed
// Maze size
#define N 4
bool solveMazeUtil(int maze[N][N], int x, int y,
int sol[N][N]);
/* A utility function to print solution matrix
sol[N][N] */
void printSolution(int sol[N][N])
{
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++)
printf(" %d ", sol[i][j]);
printf("\n");
}
}
/* A utility function to check if x, y is valid
index for N*N maze */
bool isSafe(int maze[N][N], int x, int y)
{
// if (x, y outside maze) return false
if (x >= 0 && x < N && y >= 0 &&
y < N && maze[x][y] != 0)
return true;
return false;
}
/* This function solves the Maze problem using
Backtracking. It mainly uses solveMazeUtil() to
solve the problem. It returns false if no path
is possible, otherwise return true and prints
the path in the form of 1s. Please note that
there may be more than one solutions,
this function prints one of the feasible solutions.*/
bool solveMaze(int maze[N][N])
{
int sol[N][N] = { { 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 } };
if (solveMazeUtil(maze, 0, 0, sol) == false) {
printf("Solution doesn't exist");
return false;
}
152
Chapter 27. Rat in a Maze with multiple steps or jump allowed
printSolution(sol);
return true;
}
/* A recursive utility function to solve Maze problem */
bool solveMazeUtil(int maze[N][N], int x, int y,
int sol[N][N])
{
// if (x, y is goal) return true
if (x == N - 1 && y == N - 1) {
sol[x][y] = 1;
return true;
}
// Check if maze[x][y] is valid
if (isSafe(maze, x, y) == true) {
// mark x, y as part of solution path
sol[x][y] = 1;
/* Move forward in x direction */
for (int i = 1; i <= maze[x][y] && i < N; i++) {
/* Move forward in x direction */
if (solveMazeUtil(maze, x + i, y, sol) == true)
return true;
/* If moving in x direction doesn't give
solution then Move down in y direction */
if (solveMazeUtil(maze, x, y + i, sol) == true)
return true;
}
/* If none of the above movements work then
BACKTRACK: unmark x, y as part of solution
path */
sol[x][y] = 0;
return false;
}
return false;
}
// driver program to test above function
int main()
{
int maze[N][N] = { { 2, 1, 0, 0 },
{ 3, 0, 0, 1 },
153
Chapter 27. Rat in a Maze with multiple steps or jump allowed
{ 0, 1, 0, 1 },
{ 0, 0, 0, 1 } };
solveMaze(maze);
return 0;
}
Output:
1 0 0 0
1 0 0 1
0 0 0 1
0 0 0 1
Source
https://www.geeksforgeeks.org/rat-in-a-maze-with-multiple-steps-jump-allowed/
154
Chapter 28
Naive Algorithm
The Naive Algorithm is to generate all possible configurations of numbers from 1 to 8 to fill
the empty cells. Try every configuration one by one until the correct configuration is found.
Backtracking Algorithm
Like all other Backtraking problems, we can solve this problem by one by one assigning
numbers to empty cells. Before assigning a number, we check whether it is safe to assign.
We basically check that the same number is not present to its adjacent cell (vertically,
horizontally or diagonally). After checking for safety, we assign the number, and recursively
155
Chapter 28. Fill 8 numbers in grid with given conditions
check whether this assignment leads to a solution or not. If the assignment doesn’t lead to
a solution, then we try next number for the current empty cell. And if none of the number
(1 to 8) leads to solution, we return false.
// A Backtracking program in
// C++ to solve given problem
#include <cmath>
#include <iostream>
#define N 3 // row of grid
#define M 4 // column of grid
#define UNASSIGNED -1
using namespace std;
/* Returns a boolean which indicates
whether any assigned entry within the
specified grid matches the given number. */
bool UsedInGrid(int grid[N][M], int num)
{
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++)
if (grid[i][j] == num)
return true;
}
return false;
}
/* Returns a boolean which indicates
whether it will be legal to assign
num to the given row, col location. */
bool isSafe(int grid[N][M], int row, int col, int num)
{
/* Check if 'num' is not already placed in Whole Grid*/
if (row == 0 && col == 1) {
if (UsedInGrid(grid, num)
|| (abs(num - grid[row][col + 1]) <= 1)
|| (abs(num - grid[row + 1][col]) <= 1)
156
Chapter 28. Fill 8 numbers in grid with given conditions
157
Chapter 28. Fill 8 numbers in grid with given conditions
158
Chapter 28. Fill 8 numbers in grid with given conditions
Output:
159
Chapter 28. Fill 8 numbers in grid with given conditions
3 5
7 1 8 2
4 6
Source
https://www.geeksforgeeks.org/fill-grid-1-8-numbers/
160
Chapter 29
Input : abc
Output : a ab abc ac b bc c
The idea is to sort array first. After sorting, one by one fix characters and recursively
generates all subsets starting from them. After every recursive call, we remove last
character so that next permutation can be generated.
C++
161
Chapter 29. Power Set in Lexicographic order
PHP
<?php
// PHP program to generate power
// set in lexicographic order.
// str : Stores input string
// n : Length of str.
// curr : Stores current permutation
// index : Index in current permutation, curr
function permuteRec($str, $n, $index = -1,
$curr = "")
{
// base case
if ($index == $n)
return;
162
Chapter 29. Power Set in Lexicographic order
echo $curr."\n";
for ($i = $index + 1; $i < $n; $i++)
{
$curr=$curr.$str[$i];
permuteRec($str, $n, $i, $curr);
// backtracking
$curr ="";
}
return;
}
// Generates power set in lexicographic
// order.
function powerSet($str)
{
$str = str_split($str);
sort($str);
permuteRec($str, sizeof($str));
}
// Driver code
$str = "cab";
powerSet($str);
// This code is contributed by Mithun Kumar
?>
Output :
a
ab
abc
ac
b
bc
c
Source
https://www.geeksforgeeks.org/powet-set-lexicographic-order/
163
Chapter 30
Input : N = 2, P = 7, S = 28
Output : 11 17
Explanation : 11 and 17 are primes after
prime 7 and (11 + 17 = 28)
Input : N = 3, P = 2, S = 23
Output : 3 7 13
5 7 11
Explanation : 3, 5, 7, 11 and 13 are primes
after prime 2. And (3 + 7 + 13 = 5 + 7 + 11
= 23)
Input : N = 4, P = 3, S = 54
Output : 5 7 11 31
5 7 13 29
5 7 19 23
5 13 17 19
7 11 13 23
7 11 17 19
Explanation : All are prime numbers and
their sum is 54
164
Chapter 30. Prime numbers after prime P with sum S
Approach : The approach used is to produce all the primes less than S and greater than
P. And then backtracking to find if such N primes exist whose sum equals S.
For example, S = 10, N = 2, P = 2
C++
165
Chapter 30. Prime numbers after prime P with sum S
166
Chapter 30. Prime numbers after prime P with sum S
// exclude (index)th prime
primeSum(total, N, S, index+1);
}
// function to generate all primes
void allPrime(int N, int S, int P)
{
// all primes less than S itself
for (int i = P+1; i <=S ; i++)
{
// if i is prime add it to prime vector
if (isPrime(i))
prime.push_back(i);
}
// if primes are less than N
if (prime.size() < N)
return;
primeSum(0, N, S, 0);
}
// Driver Code
int main()
{
int S = 54, N = 2, P = 3;
allPrime(N, S, P);
return 0;
}
Java
167
Chapter 30. Prime numbers after prime P with sum S
168
Chapter 30. Prime numbers after prime P with sum S
display();
return;
}
// if total is greater
// than S or if index
// has reached last
// element
if (total > S ||
index == prime.size())
return;
// add prime.get(index)
// to set vector
set.add(prime.get(index));
// include the (index)th
// prime to total
primeSum(total + prime.get(index),
N, S, index + 1);
// remove element
// from set vector
set.remove(set.size() - 1);
// exclude (index)th prime
primeSum(total, N,
S, index + 1);
}
// function to generate
// all primes
static void allPrime(int N,
int S, int P)
{
// all primes less
// than S itself
for (int i = P + 1;
i <= S ; i++)
{
// if i is prime add
// it to prime vector
if (isPrime(i))
prime.add(i);
}
// if primes are
// less than N
169
Chapter 30. Prime numbers after prime P with sum S
Python3
170
Chapter 30. Prime numbers after prime P with sum S
171
Chapter 30. Prime numbers after prime P with sum S
C#
172
Chapter 30. Prime numbers after prime P with sum S
173
Chapter 30. Prime numbers after prime P with sum S
return;
}
// if total is greater than
// S or if index has reached
// last element
if (total > S || index == prime.Count)
return;
// add prime[index]
// to set vector
set.Add(prime[index]);
// include the (index)th
// prime to total
primeSum(total + prime[index],
N, S, index + 1);
// remove element
// from set vector
set.RemoveAt(set.Count - 1);
// exclude (index)th prime
primeSum(total, N, S, index + 1);
}
// function to generate
// all primes
static void allPrime(int N,
int S, int P)
{
// all primes less than S itself
for (int i = P + 1; i <=S ; i++)
{
// if i is prime add
// it to prime vector
if (isPrime(i))
prime.Add(i);
}
// if primes are
// less than N
if (prime.Count < N)
return;
primeSum(0, N, S, 0);
}
// Driver Code
174
Chapter 30. Prime numbers after prime P with sum S
PHP
<?php
// PHP Program to print all
// N primes after prime P
// whose sum equals S
// vector to store prime
// and N primes whose
// sum equals given S
$set = array();
$prime = array();
// function to
// check prime number
function isPrime($x)
{
// square root of x
$sqroot = sqrt($x);
$flag = true;
// since 1 is not
// prime number
if ($x == 1)
return false;
// if any factor is
// found return false
for ($i = 2; $i <= $sqroot; $i++)
if ($x % $i == 0)
return false;
// no factor found
return true;
}
// function to display N
// primes whose sum equals S
175
Chapter 30. Prime numbers after prime P with sum S
function display()
{
global $set, $prime;
$length = count($set);
for ($i = 0; $i < $length; $i++)
echo ($set[$i] . " ");
echo ("\n");
}
// function to evaluate
// all possible N primes
// whose sum equals S
function primeSum($total, $N,
$S, $index)
{
global $set, $prime;
// if total equals S
// And total is reached
// using N primes
if ($total == $S &&
count($set) == $N)
{
// display the N primes
display();
return;
}
// if total is greater
// than S or if index
// has reached last element
if ($total > $S ||
$index == count($prime))
return;
// add prime[index]
// to set vector
array_push($set,
$prime[$index]);
// include the (index)th
// prime to total
primeSum($total + $prime[$index],
$N, $S, $index + 1);
// remove element
// from set vector
array_pop($set);
176
Chapter 30. Prime numbers after prime P with sum S
// exclude (index)th prime
primeSum($total, $N, $S,
$index + 1);
}
// function to generate
// all primes
function allPrime($N, $S, $P)
{
global $set, $prime;
// all primes less
// than S itself
for ($i = $P + 1;
$i <= $S ; $i++)
{
// if i is prime add
// it to prime vector
if (isPrime($i))
array_push($prime, $i);
}
// if primes are
// less than N
if (count($prime) < $N)
return;
primeSum(0, $N, $S, 0);
}
// Driver Code
$S = 54; $N = 2; $P = 3;
allPrime($N, $S, $P);
// This code is contributed by
// Manish Shaw(manishshaw1)
?>
Output:
7 47
11 43
13 41
17 37
23 31
Optimizations :
177
Chapter 30. Prime numbers after prime P with sum S
The above solution can be optimized by pre-computing all required primes usingSieve of
Eratosthenes
Improved By : manishshaw1
Source
https://www.geeksforgeeks.org/prime-numbers-after-prime-p-with-sum-s/
178
Chapter 31
Input : N = 7, D = 3
Output : 3/3+ 3 + 3
Explanation : 3/3 = 1, and 1+3+3 = 7
This is the minimum expression.
Input : N = 7, D = 4
Output : (4+4+4)/4 + 4
Explanation : (4+4+4) = 12, and 12/4 = 3 and 3+4 = 7
Also this is the minimum expression. Although
you may find another expression but that
expression can have only five 4's
Input : N = 200, D = 9
Output : Expression not found!
Explanation : Not possible within 10 digits.
179
Chapter 31. Smallest expression to represent a number using single digit
The approach we use is Backtracking. We start with the given Digit D and start multi-
plying, adding, subtracting, and dividing if possible. This process is done until we find the
total as N or we reach end and we backtrack to start another path. To find the minimum ex-
pression, we find the minimum level of the recursive tree. And then apply our backtracking
algorithm.
Let’s say N = 7, D = 3
The above approach is exponential. At every level, we recurse 4 more ways (at-most). So,
we can say the time complexity of the method is where n is the number of levels in
recursive tree (or we can say the number of times we want D to appear at-most in the
expression which in our case is 10).
Note: We use the above approach two times. First to find minimum level and then to
find the expression that is possible in that level. So, we have two passes in this approach.
Although we can get the expression in one go, but you’ll need to scratch your head for that.
180
Chapter 31. Smallest expression to represent a number using single digit
#define LIMIT 10
using namespace std;
// map that store if a number is seen or not
map<int, int> seen;
// stack for storing operators
stack<char> operators;
int minimum = LIMIT;
// function to find minimum levels in the recursive tree
void minLevel(int total, int N, int D, int level) {
// if total is equal to given N
if (total == N) {
// store if level is minimum
minimum = min(minimum, level);
return;
}
// if the last level is reached
if (level == minimum)
return;
// if total can be divided by D.
// recurse by dividing the total by D
if (total % D == 0)
minLevel(total / D, N, D, level + 1);
// recurse for total + D
minLevel(total + D, N, D, level + 1);
// if total - D is greater than 0
if (total - D > 0)
// recurse for total - D
minLevel(total - D, N, D, level + 1);
// recurse for total multiply D
minLevel(total * D, N, D, level + 1);
}
// function to generate the minimum expression
bool generate(int total, int N, int D, int level) {
// if total is equal to N
if (total == N)
181
Chapter 31. Smallest expression to represent a number using single digit
return true;
// if the last level is reached
if (level == minimum)
return false;
// if total is seen at level greater than current level
// or if we haven't seen total before. Mark the total
// as seen at current level
if (seen.find(total) == seen.end() ||
seen.find(total)->second >= level) {
seen[total] = level;
int divide = INT_MAX;
// if total is divisible by D
if (total % D == 0) {
divide = total / D;
// if divide isn't seen before
// mark it as seen
if (seen.find(divide) == seen.end())
seen[divide] = level + 1;
}
int addition = total + D;
// if addition isn't seen before
// mark it as seen
if (seen.find(addition) == seen.end())
seen[addition] = level + 1;
int subtraction = INT_MAX;
// if D can be subtracted from total
if (total - D > 0) {
subtraction = total - D;
// if subtraction isn't seen before
// mark it as seen
if (seen.find(subtraction) == seen.end())
seen[subtraction] = level + 1;
}
int multiply = total * D;
// if multiply isn't seen before
// mark it as seen
182
Chapter 31. Smallest expression to represent a number using single digit
183
Chapter 31. Smallest expression to represent a number using single digit
184
Chapter 31. Smallest expression to represent a number using single digit
minimum = LIMIT;
printExpression(200, 9);
return 0;
}
Output:
Expression: (4+4+4)/4+4
Expression: (((7+7)*7)*7+7+7)/7
Expression not found!
Source
https://www.geeksforgeeks.org/smallest-expression-represent-number-using-single-digit/
185
Chapter 32
The problem can be solved using backtracking, that is we take a path and start walking it,
if it leads us to the destination vertex then we count the path and backtrack to take another
path. If the path doesn’t leads us to the destination vertex, we discard the path.
Backtracking for above graph can be shown like this:
The red color vertex is the source vertex and the light-blue color vertex is destination, rest
are either intermediate or discarded paths.
186
Chapter 32. Count all possible paths between two vertices
187
Chapter 32. Count all possible paths between two vertices
C++
188
Chapter 32. Count all possible paths between two vertices
};
Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}
void Graph::addEdge(int u, int v)
{
// Add v to u’s list.
adj[u].push_back(v);
}
// Returns count of paths from 's' to 'd'
int Graph::countPaths(int s, int d)
{
// Mark all the vertices
// as not visited
bool *visited = new bool[V];
memset(visited, false, sizeof(visited));
// Call the recursive helper
// function to print all paths
int pathCount = 0;
countPathsUtil(s, d, visited, pathCount);
return pathCount;
}
// A recursive function to print all paths
// from 'u' to 'd'. visited[] keeps track of
// vertices in current path. path[] stores
// actual vertices and path_index is
// current index in path[]
void Graph::countPathsUtil(int u, int d, bool visited[],
int &pathCount)
{
visited[u] = true;
// If current vertex is same as destination,
// then increment count
if (u == d)
pathCount++;
// If current vertex is not destination
else
189
Chapter 32. Count all possible paths between two vertices
{
// Recur for all the vertices adjacent to
// current vertex
list<int>::iterator i;
for (i = adj[u].begin(); i != adj[u].end(); ++i)
if (!visited[*i])
countPathsUtil(*i, d, visited,
pathCount);
}
visited[u] = false;
}
// Driver Code
int main()
{
// Create a graph given in the above diagram
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(0, 3);
g.addEdge(2, 0);
g.addEdge(2, 1);
g.addEdge(1, 3);
int s = 2, d = 3;
cout << g.countPaths(s, d);
return 0;
}
Java
190
Chapter 32. Count all possible paths between two vertices
191
Chapter 32. Count all possible paths between two vertices
int n = i.next();
if (!visited[n])
{
pathCount = countPathsUtil(n, d,
visited,
pathCount);
}
}
}
visited[u] = false;
return pathCount;
}
// Returns count of
// paths from 's' to 'd'
int countPaths(int s, int d)
{
// Mark all the vertices
// as not visited
boolean visited[] = new boolean[V];
Arrays.fill(visited, false);
// Call the recursive method
// to count all paths
int pathCount = 0;
pathCount = countPathsUtil(s, d,
visited,
pathCount);
return pathCount;
}
// Driver Code
public static void main(String args[])
{
Graph g = new Graph(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(0, 3);
g.addEdge(2, 0);
g.addEdge(2, 1);
g.addEdge(1, 3);
int s = 2, d = 3;
System.out.println(g.countPaths(s, d));
}
}
192
Chapter 32. Count all possible paths between two vertices
// This code is contributed by shubhamjd.
Output:
Source
https://www.geeksforgeeks.org/count-possible-paths-two-vertices/
193
Chapter 33
sub-string(i, x) + sub-string(x+1, j)
= sub-string(j+1, l)
and
sub-string(x+1, j)+sub-string(j+1, l)
= sub-string(l+1, m)
and so on till end.
From the examples, we can see that our decision depends on first two chosen numbers.
So we choose all possible first two number for given string. Then for every chosen two
194
Chapter 33. Check if a given string is sum-string
195
Chapter 33. Check if a given string is sum-string
}
// Returns true of two substrings of ginven
// lengths of str[beg..] can cause a positive
// result.
bool checkSumStrUtil(string str, int beg,
int len1, int len2)
{
// Finding two substrings of given lengths
// and their sum
string s1 = str.substr(beg, len1);
string s2 = str.substr(beg + len1, len2);
string s3 = string_sum(s1, s2);
int s3_len = s3.size();
// if number of digits s3 is greater then
// the available string size
if (s3_len > str.size() - len1 - len2 - beg)
return false;
// we got s3 as next number in main string
if (s3 == str.substr(beg + len1 + len2, s3_len)) {
// if we reach at the end of the string
if (beg + len1 + len2 + s3_len == str.size())
return true;
// otherwise call recursively for n2, s3
return checkSumStrUtil(str, beg + len1, len2,
s3_len);
}
// we do not get s3 in main string
return false;
}
// Returns true if str is sum string, else false.
bool isSumStr(string str)
{
int n = str.size();
// choosing first two numbers and checking
// whether it is sum-string or not.
for (int i = 1; i < n; i++)
for (int j = 1; i + j < n; j++)
if (checkSumStrUtil(str, 0, i, j))
196
Chapter 33. Check if a given string is sum-string
return true;
return false;
}
// Driver code
int main()
{
cout << isSumStr("1212243660") << endl;
cout << isSumStr("123456787");
return 0;
}
Output:
1
0
Source
https://www.geeksforgeeks.org/check-given-string-sum-string/
197
Chapter 34
Print all possible strings that can be made by placing spaces - GeeksforGeeks
Given a string you need to print all possible strings that can be made by placing spaces
(zero or one) in between them.
198
Chapter 34. Print all possible strings that can be made by placing spaces
Java
199
Chapter 34. Print all possible strings that can be made by placing spaces
class Permutation
{
// Function recursively prints the strings having space pattern
// i and j are indices in 'String str' and 'buf[]' respectively
static void printPatternUtil(String str, char buf[], int i, int j, int n)
{
if(i == n)
{
buf[j] = '\0';
System.out.println(buf);
return;
}
// Either put the character
buf[j] = str.charAt(i);
printPatternUtil(str, buf, i+1, j+1, n);
// Or put a space followed by next character
buf[j] = ' ';
buf[j+1] = str.charAt(i);
printPatternUtil(str, buf, i+1, j+2, n);
}
// Function creates buf[] to store individual output string and uses
// printPatternUtil() to print all permutations
static void printPattern(String str)
{
int len = str.length();
// Buffer to hold the string containing spaces
// 2n-1 characters and 1 string terminator
char[] buf = new char[2*len];
// Copy the first character as it is, since it will be always
// at first position
buf[0] = str.charAt(0);
printPatternUtil(str, buf, 1, 1, len);
}
// Driver program
public static void main (String[] args)
{
String str = "ABCD";
printPattern(str);
}
}
200
Chapter 34. Print all possible strings that can be made by placing spaces
Python
201
Chapter 34. Print all possible strings that can be made by placing spaces
printPattern(string)
# This code is contributed by BHAVYA JAIN
C#
202
Chapter 34. Print all possible strings that can be made by placing spaces
// terminator
char []buf = new char[2*len];
// Copy the first character as it is,
// since it will be always at first
// position
buf[0] = str[0];
printPatternUtil(str, buf, 1, 1, len);
}
// Driver program
public static void Main ()
{
string str = "ABCD";
printPattern(str);
}
}
// This code is contributed by nitin mittal.
Output:
ABCD
ABC D
AB CD
AB C D
A BCD
A BC D
A B CD
A B C D
Time Complexity: Since number of Gaps are n-1, there are total 2^(n-1) patters each having
length ranging from n to 2n-1. Thus overall complexity would be O(n*(2^n)).
This article is contributed by Gaurav Sharma. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : nitin mittal
Source
https://www.geeksforgeeks.org/print-possible-strings-can-made-placing-spaces/
203
Chapter 35
Combinational Sum
Input : arr[] = 2, 4, 6, 8
x = 8
Output : [2, 2, 2, 2]
[2, 2, 4]
[2, 6]
[4, 4]
[8]
Since the problem is to get all the possible results, not the best or the number of result, thus
we don’t need to consider DP(dynamic programming), recursion is needed to handle it.
We should use the following algorithm.
204
Chapter 35. Combinational Sum
vectors).
(B) Else if sum if negative then ignore that
sub-problem.
(C) Else insert the present array in that
index to the current vector and call
the function with sum = sum-ar[index] and
index = index, then pop that element from
current index (backtrack) and call the
function with sum = sum and index = index+1
205
Chapter 35. Combinational Sum
}
}
// Returns all combinations of ar[] that have given
// sum.
vector<vector<int> > combinationSum(vector<int>& ar,
int sum)
{
// sort input array
sort(ar.begin(), ar.end());
// remove duplicates
ar.erase(unique(ar.begin(), ar.end()), ar.end());
vector<int> r;
vector<vector<int> > res;
findNumbers(ar, sum, res, r, 0);
return res;
}
// Driver code
int main()
{
vector<int> ar;
ar.push_back(2);
ar.push_back(4);
ar.push_back(6);
ar.push_back(8);
int n = ar.size();
int sum = 8; // set value of sum
vector<vector<int> > res = combinationSum(ar, sum);
// If result is empty, then
if (res.size() == 0)
{
cout << "Emptyn";
return 0;
}
// Print all combinations stored in res.
for (int i = 0; i < res.size(); i++)
{
if (res[i].size() > 0)
{
cout << " ( ";
for (int j = 0; j < res[i].size(); j++)
206
Chapter 35. Combinational Sum
Output:
( 2 2 2 2 ) ( 2 2 4 ) ( 2 6 ) ( 4 4 ) ( 8 )
Source
https://www.geeksforgeeks.org/combinational-sum/
207
Chapter 36
Combinations where every element appears twice and distance between appearances is equal
to the value - GeeksforGeeks
Given a positive number n, we need to find all the combinations of 2*n elements such that
every element from 1 to n appears exactly twice and distance between its appearances is
exactly equal to value of the element.
Examples:
Input : n = 3
Output : 3 1 2 1 3 2
2 3 1 2 1 3
All elements from 1 to 3 appear
twice and distance between two
appearances is equal to value
of the element.
Input : n = 4
Output : 4 1 3 1 2 4 3 2
2 3 4 2 1 3 1 4
Explanation
We can use backtracking to solve this problem. The idea is to all possible combinations
for the first element and recursively explore remaining element to check if they will lead to
208
Chapter 36. Combinations where every element appears twice and distance between
appearances is equal to the value
the solution or not. If current configuration doesn’t result in solution, we backtrack. Note
that an element k can be placed at position i and (i+k+1) in the output array i >= 0 and
(i+k+1) < 2*n.
Note that no combination of element is possible for some value of n like 2, 5, 6 etc.
C++
209
Chapter 36. Combinations where every element appears twice and distance between
appearances is equal to the value
void allCombinations(int n)
{
// create a vector of double the size of given number with
vector<int> arr(2*n, -1);
// all its elements initialized by 1
int elem = 1;
// start from element 1
allCombinationsRec(arr, elem, n);
}
// Driver code
int main()
{
// given number
int n = 3;
allCombinations(n);
return 0;
}
Java
210
Chapter 36. Combinations where every element appears twice and distance between
appearances is equal to the value
Python3
211
Chapter 36. Combinations where every element appears twice and distance between
appearances is equal to the value
212
Chapter 36. Combinations where every element appears twice and distance between
appearances is equal to the value
Output:
3 1 2 1 3 2
2 3 1 2 1 3
Source
https://www.geeksforgeeks.org/combinations-every-element-appears-twice-distance-appearances-equal-value/
213
Chapter 37
Input : s = "bcc"
Output : [["b", "c", "c"], ["b", "cc"]]
Input : s = "geeks"
Output : [["g", "e", "e", "k", "s"],
["g", "ee", "k", "s"]]
We have to list the all possible partitions so we will think in the direction of recursion.
When we are on index i, we incrementally check all substrings starting from i for being
palindromic. If found, we recursively solve the problem for the remaining string and add
this in our solution.
Following is the solution-
1. We will maintain a 2-dimensional vector for storing all possible partitions and a tem-
porary vector for storing the current partition, new starting index of string to check
partitions as we have already checked partitions before this index.
2. Now keep on iterating further on string and check if it is palindrome or not.
3. If it is a palindrome than add this string in current partitions vector. Recurse on
this new string if it is not the end of the string. After coming back again change the
current partition vector to the old one as it might have changed in the recursive step.
214
Chapter 37. Print all palindromic partitions of a string
4. If we reach the end of string while iterating than we have our partitions in our tem-
porary vector so we will add it in results.
To check whether it’s a palindrome or not, iterate on string by taking two pointers.
Initialize the first to start and other to end of string. If both characters are same increase
the first and decrease the last pointer and keep on iterating until first is less than last one.
215
Chapter 37. Print all palindromic partitions of a string
if (index == 0)
temp.clear();
for (int i = index; i < len; ++i)
{
str = str + s[i];
if (checkPalindrome(str))
{
temp.push_back(str);
if (i+1 < len)
addStrings(v,s,temp,i+1);
else
v.push_back(temp);
temp = current;
}
}
return;
}
// Generates all palindromic partitions of 's' and
// stores the result in 'v'.
void partition(string s, vector<vector<string> >&v)
{
vector<string> temp;
addStrings(v, s, temp, 0);
printSolution(v);
return;
}
// Driver code
int main()
{
string s = "geeks";
vector<vector<string> > partitions;
partition(s, partitions);
return 0;
}
Java
216
Chapter 37. Print all palindromic partitions of a string
len--;
for (int i=0; i<len; i++)
{
if (str.charAt(i) != str.charAt(len))
return false;
len--;
}
return true;
}
// Prints the partition list
static void printSolution(ArrayList<ArrayList<String>>
partitions)
{
for(ArrayList<String> i: partitions)
{
for(String j: i)
{
System.out.print(j+" ");
}
System.out.println();
}
}
// Goes through all indexes and recursively add remaining
// partitions if current string is palindrome.
static ArrayList<ArrayList<String>> addStrings(ArrayList<
ArrayList<String>> v, String s, ArrayList<String> temp,
int index)
{
int len = s.length();
String str = "";
ArrayList<String> current = new ArrayList<>(temp);
if (index == 0)
temp.clear();
// Iterate over the string
for (int i = index; i < len; ++i)
{
str = str + s.charAt(i);
// check whether the substring is
// palindromic or not
if (checkPalindrome(str))
{
// if palindrome add it to temp list
temp.add(str);
217
Chapter 37. Print all palindromic partitions of a string
if (i + 1 < len)
{
// recurr to get all the palindromic
// partitions for the substrings
v = addStrings(v,s,temp,i+1);
}
else
{
// if end of the string is reached
// add temp to v
v.add(temp);
}
// temp is reinitialize with the
// current i.
temp = new ArrayList<>(current);
}
}
return v;
}
// Generates all palindromic partitions of 's' and
// stores the result in 'v'.
static void partition(String s, ArrayList<ArrayList<
String>> v)
{
// temporary ArrayList to store each
// palindromic string
ArrayList<String> temp = new ArrayList<>();
// calling addString method it adds all
// the palindromic partitions to v
v = addStrings(v, s, temp, 0);
// printing the solution
printSolution(v);
}
// Driver code
public static void main(String args[])
{
String s = "geeks";
ArrayList<ArrayList<String>> partitions = new
ArrayList<>();
partition(s, partitions);
}
}
218
Chapter 37. Print all palindromic partitions of a string
Output :
g e e k s
g ee k s
Related Article:
Dynamic Programming | Set 17 (Palindrome Partitioning)
Source
https://www.geeksforgeeks.org/print-palindromic-partitions-string/
219
Chapter 38
Input: "ilikesamsungmobile"
Output: i like sam sung mobile
i like samsung mobile
Input: "ilikeicecreamandmango"
Output: i like ice cream and man go
i like ice cream and mango
i like icecream and man go
i like icecream and mango
220
Chapter 38. Word Break Problem using Backtracking
next word. And this process is recursive because to find out whether the right portion is
separable or not, we need the same logic. So we will use recursion and backtracking to
solve this problem. To keep track of the found words we will use a stack. Whenever the
right portion of the string does not make valid words, we pop the top string from stack and
continue finding.
221
Chapter 38. Word Break Problem using Backtracking
Output:
First Test:
i love ice cream and man go
i love ice cream and mango
i love icecream and man go
i love icecream and mango
Second Test:
i love sam sung mobile
i love samsung mobile
Source
https://www.geeksforgeeks.org/word-break-problem-using-backtracking/
222
Chapter 39
We can solve this problem recursively, we keep an array for sum of each partition and a
boolean array to check whether an element is already taken into some partition or not.
First we need to check some base cases,
If K is 1, then we already have our answer, complete array is only subset with same sum.
If N < K, then it is not possible to divide array into subsets with equal sum, because we
can’t divide the array into more than N parts.
If sum of array is not divisible by K, then it is not possible to divide the array. We will
proceed only if k divides sum. Our goal reduces to divide array into K parts where sum of
each part should be array_sum/K
In below code a recursive method is written which tries to add array element into some subset.
If sum of this subset reaches required sum, we iterate for next part recursively, otherwise we
223
Chapter 39. Partition of a set into K subsets with equal sum
backtrack for different set of elements. If number of subsets whose sum reaches the required
sum is (K-1), we flag that it is possible to partition array into K parts with equal sum,
because remaining elements already have a sum equal to required sum.
224
Chapter 39. Partition of a set into K subsets with equal sum
// mark the element and include into current partition sum
taken[i] = true;
subsetSum[curIdx] += arr[i];
bool nxt = isKPartitionPossibleRec(arr, subsetSum, taken,
subset, K, N, curIdx, i - 1);
// after recursive call unmark the element and remove from
// subsetition sum
taken[i] = false;
subsetSum[curIdx] -= arr[i];
if (nxt)
return true;
}
}
return false;
}
// Method returns true if arr can be partitioned into K subsets
// with equal sum
bool isKPartitionPossible(int arr[], int N, int K)
{
// If K is 1, then complete array will be our answer
if (K == 1)
return true;
// If total number of partitions are more than N, then
// division is not possible
if (N < K)
return false;
// if array sum is not divisible by K then we can't divide
// array into K partitions
int sum = 0;
for (int i = 0; i < N; i++)
sum += arr[i];
if (sum % K != 0)
return false;
// the sum of each subset should be subset (= sum / K)
int subset = sum / K;
int subsetSum[K];
bool taken[N];
// Initialize sum of each subset from 0
for (int i = 0; i < K; i++)
subsetSum[i] = 0;
// mark all elements as not taken
225
Chapter 39. Partition of a set into K subsets with equal sum
Output:
Improved By : ayush0824
Source
https://www.geeksforgeeks.org/partition-set-k-subsets-equal-sum/
226
Chapter 40
This problem is an extension of longest common subsequence. We first find length of LCS
and store all LCS in 2D table using Memoization (or Dynamic Programming). Then we
search all characters from ‘a’ to ‘z’ (to output sorted order) in both strings. If a character is
found in both strings and current positions of character lead to LCS, we recursively search
all occurrences with current LCS length plus 1.
Below is the implementation of algorithm.
227
Chapter 40. Print all longest common sub-sequences in lexicographical order
228
Chapter 40. Print all longest common sub-sequences in lexicographical order
}
// if we are done with all the characters of both string
if (indx1==len1 || indx2==len2)
return;
// here we have to print all sub-sequences lexicographically,
// that's why we start from 'a'to'z' if this character is
// present in both of them then append it in data[] and same
// remaining part
for (char ch='a'; ch<='z'; ch++)
{
// done is a flag to tell that we have printed all the
// subsequences corresponding to current character
bool done = false;
for (int i=indx1; i<len1; i++)
{
// if character ch is present in str1 then check if
// it is present in str2
if (ch==str1[i])
{
for (int j=indx2; j<len2; j++)
{
// if ch is present in both of them and
// remaining length is equal to remaining
// lcs length then add ch in sub-sequenece
if (ch==str2[j] &&
lcs(str1, str2, len1, len2, i, j) == lcslen-currlcs)
{
data[currlcs] = ch;
printAll(str1, str2, len1, len2, data, i+1, j+1, currlcs+1);
done = true;
break;
}
}
}
// If we found LCS beginning with current character.
if (done)
break;
}
}
}
// This function prints all LCS of str1 and str2
// in lexicographic order.
void prinlAllLCSSorted(string str1, string str2)
229
Chapter 40. Print all longest common sub-sequences in lexicographical order
{
// Find lengths of both strings
int len1 = str1.length(), len2 = str2.length();
// Find length of LCS
memset(dp, -1, sizeof(dp));
lcslen = lcs(str1, str2, len1, len2, 0, 0);
// Print all LCS using recursive backtracking
// data[] is used to store individual LCS.
char data[MAX];
printAll(str1, str2, len1, len2, data, 0, 0, 0);
}
// Driver program to run the case
int main()
{
string str1 = "abcabcaa", str2 = "acbacba";
prinlAllLCSSorted(str1, str2);
return 0;
}
Output:
ababa
abaca
abcba
acaba
acaca
acbaa
acbca
Source
https://www.geeksforgeeks.org/print-longest-common-sub-sequences-lexicographical-order/
230
Chapter 41
As we need to generate all possible output we will backtrack among all states by removing
one opening or closing bracket and check if they are valid if invalid then add the removed
bracket back and go for next state. We will use BFS for moving through states, use of BFS
will assure removal of minimal number of brackets because we traverse into states level by
level and each level corresponds to one extra bracket removal. Other than this BFS involve
no recursion so overhead of passing parameters is also saved.
Below code has a method isValidString to check validity of string, it counts open and closed
parenthesis at each index ignoring non-parenthesis character. If at any instant count of close
parenthesis becomes more than open then we return false else we keep update the count
variable.
231
Chapter 41. Remove Invalid Parentheses
232
Chapter 41. Remove Invalid Parentheses
Output:
(())()
()()()
(v)
()v
Source
https://www.geeksforgeeks.org/remove-invalid-parentheses/
233
Chapter 42
Input: S = {1, 2, 2}
Output: {}, {1}, {2}, {1, 2}, {2, 2}, {1, 2, 2}
Explanation:
The total subsets of given set are -
{}, {1}, {2}, {2}, {1, 2}, {1, 2}, {2, 2}, {1, 2, 2}
Here {2} and {1, 2} are repeated twice so they are considered
only once in the output
234
Chapter 42. Find all distinct subsets of a given set
// Utility function to split the string using a delim. Refer -
// http://stackoverflow.com/questions/236129/split-a-string-in-c
vector<string> split(const string &s, char delim)
{
vector<string> elems;
stringstream ss(s);
string item;
while (getline(ss, item, delim))
elems.push_back(item);
return elems;
}
// Function to find all subsets of given set. Any repeated
// subset is considered only once in the output
int printPowerSet(int arr[], int n)
{
vector<string> list;
/* Run counter i from 000..0 to 111..1*/
for (int i = 0; i < (int) pow(2, n); i++)
{
string subset = "";
// consider each element in the set
for (int j = 0; j < n; j++)
{
// Check if jth bit in the i is set. If the bit
// is set, we consider jth element from set
if ((i & (1 << j)) != 0)
subset += to_string(arr[j]) + "|";
}
// if subset is encountered for the first time
// If we use set<string>, we can directly insert
if (find(list.begin(), list.end(), subset) == list.end())
list.push_back(subset);
}
// consider every subset
for (string subset : list)
{
// split the subset and print its elements
vector<string> arr = split(subset, '|');
for (string str: arr)
cout << str << " ";
cout << endl;
235
Chapter 42. Find all distinct subsets of a given set
}
}
// Driver code
int main()
{
int arr[] = { 10, 12, 12 };
int n = sizeof(arr)/sizeof(arr[0]);
printPowerSet(arr, n);
return 0;
}
Output:
10
12
10 12
12 12
10 12 12
This article is contributed by Aditya Goel. If you like GeeksforGeeks and would like to
contribute, you can also write an article using contribute.GeeksforGeeks.org or mail your
article to contribute@GeeksforGeeks.org. See your article appearing on the GeeksforGeeks
main page and help other Geeks.
Source
https://www.geeksforgeeks.org/find-distinct-subsets-given-set/
236
Chapter 43
Input:
A 12 x 10 matrix with landmines marked as 0
[ 1 1 1 1 1 1 1 1 1 1 ]
[ 1 0 1 1 1 1 1 1 1 1 ]
[ 1 1 1 0 1 1 1 1 1 1 ]
[ 1 1 1 1 0 1 1 1 1 1 ]
[ 1 1 1 1 1 1 1 1 1 1 ]
[ 1 1 1 1 1 0 1 1 1 1 ]
[ 1 0 1 1 1 1 1 1 0 1 ]
[ 1 1 1 1 1 1 1 1 1 1 ]
[ 1 1 1 1 1 1 1 1 1 1 ]
[ 0 1 1 1 1 0 1 1 1 1 ]
[ 1 1 1 1 1 1 1 1 1 1 ]
[ 1 1 1 0 1 1 1 1 1 1 ]
Output:
Length of shortest safe route is 13 (Highlighted in Bold)
237
Chapter 43. Find shortest safe route in a path with landmines
The idea is to use Backtracking. We first mark all adjacent cells of the landmines as unsafe.
Then for each safe cell of first column of the matrix, we move forward in all allowed directions
and recursively checks if they leads to the destination or not. If destination is found, we
update the value of shortest path else if none of the above solutions work we return false
from our function.
Below is C++ implementation of above idea –
238
Chapter 43. Find shortest safe route in a path with landmines
{
// if a landmines is found
if (mat[i][j] == 0)
{
// mark all adjacent cells
for (int k = 0; k < 4; k++)
if (isValid(i + rowNum[k], j + colNum[k]))
mat[i + rowNum[k]][j + colNum[k]] = -1;
}
}
}
// mark all found adjacent cells as unsafe
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
if (mat[i][j] == -1)
mat[i][j] = 0;
}
}
// Uncomment below lines to print the path
/*for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
cout << std::setw(3) << mat[i][j];
}
cout << endl;
}*/
}
// Function to find shortest safe Route in the
// matrix with landmines
// mat[][] - binary input matrix with safe cells marked as 1
// visited[][] - store info about cells already visited in
// current route
// (i, j) are cordinates of the current cell
// min_dist --> stores minimum cost of shortest path so far
// dist --> stores current path cost
void findShortestPathUtil(int mat[R][C], int visited[R][C],
int i, int j, int &min_dist, int dist)
{
// if destination is reached
if (j == C-1)
{
// update shortest path found so far
239
Chapter 43. Find shortest safe route in a path with landmines
240
Chapter 43. Find shortest safe route in a path with landmines
241
Chapter 43. Find shortest safe route in a path with landmines
Output:
Source
https://www.geeksforgeeks.org/find-shortest-safe-route-in-a-path-with-landmines/
242
Chapter 44
The idea is to use Backtracking. We start from the source cell of the matrix, move forward
in all four allowed directions and recursively checks if they leads to the solution or not. If
destination is found, we update the value of longest path else if none of the above solutions
work we return false from our function.
Below is C++ implementation of above idea –
243
Chapter 44. Longest Possible Route in a Matrix with Hurdles
#include <bits/stdc++.h>
using namespace std;
#define R 3
#define C 10
// A Pair to store status of a cell. found is set to
// true of destination is reachable and value stores
// distance of longest path
struct Pair
{
// true if destination is found
bool found;
// stores cost of longest path from current cell to
// destination cell
int value;
};
// Function to find Longest Possible Route in the
// matrix with hurdles. If the destination is not reachable
// the function returns false with cost INT_MAX.
// (i, j) is source cell and (x, y) is destination cell.
Pair findLongestPathUtil(int mat[R][C], int i, int j,
int x, int y, bool visited[R][C])
{
// if (i, j) itself is destination, return true
if (i == x && j == y)
{
Pair p = { true, 0 };
return p;
}
// if not a valid cell, return false
if (i < 0 || i >= R || j < 0 || j >= C ||
mat[i][j] == 0 || visited[i][j])
{
Pair p = { false, INT_MAX };
return p;
}
// include (i, j) in current path i.e.
// set visited(i, j) to true
visited[i][j] = true;
// res stores longest path from current cell (i, j) to
// destination cell (x, y)
int res = INT_MIN;
244
Chapter 44. Longest Possible Route in a Matrix with Hurdles
// go left from current cell
Pair sol = findLongestPathUtil(mat, i, j - 1, x, y, visited);
// if destination can be reached on going left from current
// cell, update res
if (sol.found)
res = max(res, sol.value);
// go right from current cell
sol = findLongestPathUtil(mat, i, j + 1, x, y, visited);
// if destination can be reached on going right from current
// cell, update res
if (sol.found)
res = max(res, sol.value);
// go up from current cell
sol = findLongestPathUtil(mat, i - 1, j, x, y, visited);
// if destination can be reached on going up from current
// cell, update res
if (sol.found)
res = max(res, sol.value);
// go down from current cell
sol = findLongestPathUtil(mat, i + 1, j, x, y, visited);
// if destination can be reached on going down from current
// cell, update res
if (sol.found)
res = max(res, sol.value);
// Backtrack
visited[i][j] = false;
// if destination can be reached from current cell,
// return true
if (res != INT_MIN)
{
Pair p = { true, 1 + res };
return p;
}
// if destination can't be reached from current cell,
// return false
else
{
245
Chapter 44. Longest Possible Route in a Matrix with Hurdles
Output:
246
Chapter 44. Longest Possible Route in a Matrix with Hurdles
Source
https://www.geeksforgeeks.org/longest-possible-route-in-a-matrix-with-hurdles/
247
Chapter 45
Input:
string - GraphTreesGraph
pattern - aba
Output:
a->Graph
b->Trees
Input:
string - GraphGraphGraph
pattern - aaa
Output:
a->Graph
Input:
string - GeeksforGeeks
pattern - GfG
Output:
G->Geeks
f->for
248
Chapter 45. Match a pattern and String without using regular expressions
Input:
string - GeeksforGeeks
pattern - GG
Output:
No solution exists
We can solve this problem with the help of Backtracking. For each character in the pattern,
if the character is not seen before, we consider all possible sub-strings and recurse to see
if it leads to the solution or not. We maintain a map that stores sub-string mapped to a
pattern character. If pattern character is seen before, we use the same sub-string present in
the map. If we found a solution, for each distinct character in the pattern, we print string
mapped to it using our map.
Below is C++ implementation of above idea –
249
Chapter 45. Match a pattern and String without using regular expressions
string s = map[ch];
int len = s.size();
// consider next len characters of str
string subStr = str.substr(i, len);
// if next len characters of string str
// don't match with s, return false
if (subStr.compare(s))
return false;
// if it matches, recurse for remaining characters
return patternMatchUtil(str, n, i + len, pat, m,
j + 1, map);
}
// If character is seen for first time, try out all
// remaining characters in the string
for (int len = 1; len <= n - i; len++)
{
// consider substring that starts at position i
// and spans len characters and add it to map
map[ch] = str.substr(i, len);
// see if it leads to the solution
if (patternMatchUtil(str, n, i + len, pat, m,
j + 1, map))
return true;
// if not, remove ch from the map
map.erase(ch);
}
return false;
}
// A wrapper over patternMatchUtil()function
bool patternMatch(string str, string pat, int n, int m)
{
if (n < m)
return false;
// create an empty hashmap
unordered_map<char, string> map;
// store result in a boolean variable res
bool res = patternMatchUtil(str, n, 0, pat, m, 0, map);
250
Chapter 45. Match a pattern and String without using regular expressions
Output:
f->for
G->Geeks
Source
https://www.geeksforgeeks.org/match-a-pattern-and-string-without-using-regular-expressions/
251
Chapter 46
Input: M = 254, K = 1
Output: 524
Input: M = 254, K = 2
Output: 542
Input: M = 68543, K = 1
Output: 86543
Input: M = 7599, K = 2
Output: 9975
Input: M = 76543, K = 1
Output: 76543
Input: M = 129814999, K = 4
Output: 999984211
Idea is to consider every digit and swap it with digits following it one at a time and see if
it leads to the maximum number. We repeat the process K times. The code can be further
optimized if we swap only if current digit is less than the following digit.
Below is C++ implementation of above idea –
252
Chapter 46. Find Maximum number possible by doing at-most K swaps
253
Chapter 46. Find Maximum number possible by doing at-most K swaps
int k = 4;
string max = str;
findMaximumNum(str, k, max);
cout << max << endl;
return 0;
}
Output:
999984211
The above code can further be optimized by stopping our search if all digits are already
sorted in decreasing order. Please do share with us if you find more efficient ways to solve
this problem.
Exercise :
1. Find minimum integer possible by doing at-least K swap operations on its digits.
2. Find maximum/minimum integer possible by doing exactly K swap operations on its
digits.
Source
https://www.geeksforgeeks.org/find-maximum-number-possible-by-doing-at-most-k-swaps/
254
Chapter 47
Input: 9 x 9 maze
[ 3, 5, 4, 4, 7, 3, 4, 6, 3 ]
[ 6, 7, 5, 6, 6, 2, 6, 6, 2 ]
[ 3, 3, 4, 3, 2, 5, 4, 7, 2 ]
[ 6, 5, 5, 1, 2, 3, 6, 5, 6 ]
[ 3, 3, 4, 3, 0, 1, 4, 3, 4 ]
[ 3, 5, 4, 3, 2, 2, 3, 3, 5 ]
[ 3, 5, 4, 3, 2, 6, 4, 4, 3 ]
[ 3, 5, 1, 3, 7, 5, 3, 6, 4 ]
[ 6, 2, 4, 3, 4, 5, 4, 5, 1 ]
Output:
(0, 0) -> (0, 3) -> (0, 7) ->
(6, 7) -> (6, 3) -> (3, 3) ->
(3, 4) -> (5, 4) -> (5, 2) ->
(1, 2) -> (1, 7) -> (7, 7) ->
(7, 1) -> (2, 1) -> (2, 4) ->
(4, 4) -> MID
255
Chapter 47. Find paths from corner cell to middle cell in maze
The idea is to use backtracking. We start with each corner cell of the maze and recursively
checks if it leads to the solution or not. Following is the Backtracking algorithm –
If destination is reached
Else
256
Chapter 47. Find paths from corner cell to middle cell in maze
257
Chapter 47. Find paths from corner cell to middle cell in maze
path.pop_back();
// remove cell from current path
visited.erase(next);
}
}
}
// Function to find a path from corner cell to
// middle cell in maze contaning positive numbers
void findPathInMaze(int maze[N][N])
{
// list to store complete path
// from source to destination
list<pair<int, int> > path;
// to store cells already visisted in current path
set<pair<int, int> > visited;
// Consider each corners as the starting
// point and search in maze
for (int i = 0; i < 4; ++i)
{
int x = _row[i];
int y = _col[i];
// Constructs a pair object
pair<int, int> pt = make_pair(x, y);
// mark cell as visited
visited.insert(pt);
// add cell to current path
path.push_back(pt);
findPathInMazeUtil(maze, path, visited, pt);
// backtrack
path.pop_back();
// remove cell from current path
visited.erase(pt);
}
}
int main()
{
int maze[N][N] =
258
Chapter 47. Find paths from corner cell to middle cell in maze
{
{ 3, 5, 4, 4, 7, 3, 4, 6, 3 },
{ 6, 7, 5, 6, 6, 2, 6, 6, 2 },
{ 3, 3, 4, 3, 2, 5, 4, 7, 2 },
{ 6, 5, 5, 1, 2, 3, 6, 5, 6 },
{ 3, 3, 4, 3, 0, 1, 4, 3, 4 },
{ 3, 5, 4, 3, 2, 2, 3, 3, 5 },
{ 3, 5, 4, 3, 2, 6, 4, 4, 3 },
{ 3, 5, 1, 3, 7, 5, 3, 6, 4 },
{ 6, 2, 4, 3, 4, 5, 4, 5, 1 }
};
findPathInMaze(maze);
return 0;
}
Output :
Source
https://www.geeksforgeeks.org/find-paths-from-corner-cell-to-middle-cell-in-maze/
259
Chapter 48
Input : Source s = 0, k = 58
Output : True
There exists a simple path 0 -> 7 -> 1
-> 2 -> 8 -> 6 -> 5 -> 3 -> 4
Which has a total distance of 60 km which
is more than 58.
Input : Source s = 0, k = 62
Output : False
We strongly recommend you to minimize your browser and try this yourself
first.
One important thing to note is, simply doing BFS or DFS and picking the longest edge at
every step would not work. The reason is, a shorter edge can produce longer path due to
higher weight edges connected through it.
260
Chapter 48. Find if there is a path of more than k length from a source
The idea is to use Backtracking. We start from given source, explore all paths from current
vertex. We keep track of current distance from source. If distance becomes more than k, we
return true. If a path doesn’t produces more than k distance, we backtrack.
How do we make sure that the path is simple and we don’t loop in a cycle? The idea is to
keep track of current path vertices in an array. Whenever we add a vertex to path, we check
if it already exists or not in current path. If it exists, we ignore the edge.
Below is C++ implementation of above idea.
261
Chapter 48. Find if there is a path of more than k length from a source
// Prints shortest paths from src to all other vertices
bool Graph::pathMoreThanKUtil(int src, int k, vector<bool> &path)
{
// If k is 0 or negative, return true;
if (k <= 0)
return true;
// Get all adjacent vertices of source vertex src and
// recursively explore all paths from src.
list<iPair>::iterator i;
for (i = adj[src].begin(); i != adj[src].end(); ++i)
{
// Get adjacent vertex and weight of edge
int v = (*i).first;
int w = (*i).second;
// If vertex v is already there in path, then
// there is a cycle (we ignore this edge)
if (path[v] == true)
continue;
// If weight of is more than k, return true
if (w >= k)
return true;
// Else add this vertex to path
path[v] = true;
// If this adjacent can provide a path longer
// than k, return true.
if (pathMoreThanKUtil(v, k-w, path))
return true;
// Backtrack
path[v] = false;
}
// If no adjacent could produce longer path, return
// false
return false;
}
// Allocates memory for adjacency list
Graph::Graph(int V)
{
this->V = V;
adj = new list<iPair> [V];
262
Chapter 48. Find if there is a path of more than k length from a source
}
// Utility function to an edge (u, v) of weight w
void Graph::addEdge(int u, int v, int w)
{
adj[u].push_back(make_pair(v, w));
adj[v].push_back(make_pair(u, w));
}
// Driver program to test methods of graph class
int main()
{
// create the graph given in above fugure
int V = 9;
Graph g(V);
// making above shown graph
g.addEdge(0, 1, 4);
g.addEdge(0, 7, 8);
g.addEdge(1, 2, 8);
g.addEdge(1, 7, 11);
g.addEdge(2, 3, 7);
g.addEdge(2, 8, 2);
g.addEdge(2, 5, 4);
g.addEdge(3, 4, 9);
g.addEdge(3, 5, 14);
g.addEdge(4, 5, 10);
g.addEdge(5, 6, 2);
g.addEdge(6, 7, 1);
g.addEdge(6, 8, 6);
g.addEdge(7, 8, 7);
int src = 0;
int k = 62;
g.pathMoreThanK(src, k)? cout << "Yes\n" :
cout << "No\n";
k = 60;
g.pathMoreThanK(src, k)? cout << "Yes\n" :
cout << "No\n";
return 0;
}
Output:
No
Yes
263
Chapter 48. Find if there is a path of more than k length from a source
Exercise:
Modify the above solution to find weight of longest path from a given source.
Time Complexity: O(n!)
Explanation:
From the source node, we one-by-one visit all the paths and check if the total weight is
greater than k for each path. So, the worst case will be when the number of possible paths
is maximum. This is the case when every node is connected to every other node.
Beginning from the source node we have n-1 adjacent nodes. The time needed for a path to
connect any two nodes is 2. One for joining the source and the next adjacent vertex. One
for breaking the connection between the source and the old adjacent vertex.
After selecting a node out of n-1 adjacent nodes, we are left with n-2 adjacent nodes (as the
source node is already included in the path) and so on at every step of selecting a node our
problem reduces by 1 node.
We can write this in the form of a recurrence relation as: F(n) = n*(2+F(n-1))
This expands to: 2n + 2n*(n-1) + 2n*(n-1)*(n-2) + ……. + 2n(n-1)(n-2)(n-3)…..1
As n times 2n(n-1)(n-2)(n-3)….1 is greater than the given expression so we can safely say
time complexity is: n*2*n!
Here in the question the first node is defined so time complexity becomes
F(n-1) = 2(n-1)*(n-1)! = 2*n*(n-1)! – 2*1*(n-1)! = 2*n!-2*(n-1)! = O(n!)
This article is contributed by Shivam Gupta. The explanation for time complexity
is contributed by Pranav Nambiar. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above
Source
https://www.geeksforgeeks.org/find-if-there-is-a-path-of-more-than-k-length-from-a-source/
264
Chapter 49
Input: n = 3
Output: res[] = {3, 1, 2, 1, 3, 2}
Input: n = 2
Output: Not Possible
Input: n = 4
Output: res[] = {4, 1, 3, 1, 2, 4, 3, 2}
We strongly recommend to minimize the browser and try this yourself first.
One solution is to Backtracking. The idea is simple, we place two instances of n at a place,
then recur for n-1. If recurrence is successful, we return true, else we backtrack and try
placing n at different location. Following is C implementation of the idea.
265
Chapter 49. Fill two instances of all numbers from 1 to n in a specific way
266
Chapter 49. Fill two instances of all numbers from 1 to n in a specific way
{
fill(7);
return 0;
}
Output:
7 3 6 2 5 3 2 4 7 6 5 1 4 1
The above solution may not be the best possible solution. There seems to be a pattern in
the output. I an Looking for a better solution from other geeks.
This article is contributed by Asif. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above
Source
https://www.geeksforgeeks.org/fill-two-instances-numbers-1-n-specific-way/
267
Chapter 50
The idea is to do Depth First Traversal of given directed graph. Start the traversal from
source. Keep storing the visited vertices in an array say ‘path[]’. If we reach the destination
vertex, print contents of path[]. The important thing is to mark current vertices in path[]
as visited also, so that the traversal doesn’t go in a cycle.
Following is implementation of above idea.
C/C++
268
Chapter 50. Print all paths from a given source to a destination
269
Chapter 50. Print all paths from a given source to a destination
// A recursive function to print all paths from 'u' to 'd'.
// visited[] keeps track of vertices in current path.
// path[] stores actual vertices and path_index is current
// index in path[]
void Graph::printAllPathsUtil(int u, int d, bool visited[],
int path[], int &path_index)
{
// Mark the current node and store it in path[]
visited[u] = true;
path[path_index] = u;
path_index++;
// If current vertex is same as destination, then print
// current path[]
if (u == d)
{
for (int i = 0; i<path_index; i++)
cout << path[i] << " ";
cout << endl;
}
else // If current vertex is not destination
{
// Recur for all the vertices adjacent to current vertex
list<int>::iterator i;
for (i = adj[u].begin(); i != adj[u].end(); ++i)
if (!visited[*i])
printAllPathsUtil(*i, d, visited, path, path_index);
}
// Remove current vertex from path[] and mark it as unvisited
path_index--;
visited[u] = false;
}
// Driver program
int main()
{
// Create a graph given in the above diagram
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(0, 3);
g.addEdge(2, 0);
g.addEdge(2, 1);
g.addEdge(1, 3);
int s = 2, d = 3;
270
Chapter 50. Print all paths from a given source to a destination
cout << "Following are all different paths from " << s
<< " to " << d << endl;
g.printAllPaths(s, d);
return 0;
}
Java
271
Chapter 50. Print all paths from a given source to a destination
272
Chapter 50. Print all paths from a given source to a destination
Python
273
Chapter 50. Print all paths from a given source to a destination
def __init__(self,vertices):
#No. of vertices
self.V= vertices
# default dictionary to store graph
self.graph = defaultdict(list)
# function to add an edge to graph
def addEdge(self,u,v):
self.graph[u].append(v)
'''A recursive function to print all paths from 'u' to 'd'.
visited[] keeps track of vertices in current path.
path[] stores actual vertices and path_index is current
index in path[]'''
def printAllPathsUtil(self, u, d, visited, path):
# Mark the current node as visited and store in path
visited[u]= True
path.append(u)
# If current vertex is same as destination, then print
# current path[]
if u ==d:
print path
else:
# If current vertex is not destination
#Recur for all the vertices adjacent to this vertex
for i in self.graph[u]:
if visited[i]==False:
self.printAllPathsUtil(i, d, visited, path)
# Remove current vertex from path[] and mark it as unvisited
path.pop()
visited[u]= False
# Prints all paths from 's' to 'd'
def printAllPaths(self,s, d):
# Mark all the vertices as not visited
visited =[False]*(self.V)
# Create an array to store paths
path = []
# Call the recursive helper function to print all paths
self.printAllPathsUtil(s, d,visited, path)
274
Chapter 50. Print all paths from a given source to a destination
# Create a graph given in the above diagram
g = Graph(4)
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(0, 3)
g.addEdge(2, 0)
g.addEdge(2, 1)
g.addEdge(1, 3)
s = 2 ; d = 3
print ("Following are all different paths from %d to %d :" %(s, d))
g.printAllPaths(s, d)
#This code is contributed by Neelam Yadav
Output:
This article is contributed by Shivam Gupta. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
https://www.geeksforgeeks.org/find-paths-given-source-destination/
275
Chapter 51
Print all possible paths from top left to bottom right of a mXn matrix - GeeksforGeeks
The problem is to print all the possible paths from top left to bottom right of a mXn matrix
with the constraints that from each cell you can either move only to right or down.
Examples :
Input : 1 2 3
4 5 6
Output : 1 4 5 6
1 2 5 6
1 2 3 6
Input : 1 2
3 4
Output : 1 2 4
1 3 4
The algorithm is a simple recursive algorithm, from each cell first print all paths by going
down and then print all paths by going right. Do this recursively for each cell encountered.
Following is C++ implementation of the above algorithm.
276
Chapter 51. Print all possible paths from top left to bottom right of a mXn matrix
277
Chapter 51. Print all possible paths from top left to bottom right of a mXn matrix
Output:
1 4 5 6
1 2 5 6
1 2 3 6
Note that in the above code, the last line of printAllPathsUtil() is commented, If we un-
comment this line, we get all the paths from the top left to bottom right of a nXm matrix
if the diagonal movements are also allowed. And also if moving to some of the cells are not
permitted then the same code can be improved by passing the restriction array to the above
function and that is left as an exercise.
This article is contributed by Hariprasad NG. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Python implementation
278
Chapter 51. Print all possible paths from top left to bottom right of a mXn matrix
print(path)
allPaths.append(path)
return
# if we reach to the right most corner, we can only move down
if j == n-1:
for k in range(i,m):
path[indx+k-i] = maze[k][j]
#path.append(maze[j][k])
# if we hit this block, it means one path is completed.
# Add it to paths list and print
print(path)
allPaths.append(path)
return
# add current element to the path list
#path.append(maze[i][j])
path[indx] = maze[i][j]
# move down in y direction and call findPathsUtil recursively
findPathsUtil(maze, m, n, i+1, j, path, indx+1)
# move down in y direction and call findPathsUtil recursively
findPathsUtil(maze, m, n, i, j+1, path, indx+1)
if __name__ == '__main__':
maze = [[1,2,3],
[4,5,6],
[7,8,9]]
findPaths(maze,3,3)
#print(allPaths)
Output:
[1, 4, 7, 8, 9]
[1, 4, 5, 8, 9]
[1, 4, 5, 6, 9]
[1, 2, 5, 8, 9]
[1, 2, 5, 6, 9]
[1, 2, 3, 6, 9]
Improved By : ashritkumar
Source
https://www.geeksforgeeks.org/print-all-possible-paths-from-top-left-to-bottom-right-of-a-mxn-matrix/
279
Chapter 52
C/C++
280
Chapter 52. Write a program to print all permutations of a given string
#include <string.h>
/* Function to swap values at two pointers */
void swap(char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
/* Function to print permutations of string
This function takes three parameters:
1. String
2. Starting index of the string
3. Ending index of the string. */
void permute(char *a, int l, int r)
{
int i;
if (l == r)
printf("%s\n", a);
else
{
for (i = l; i <= r; i++)
{
swap((a+l), (a+i));
permute(a, l+1, r);
swap((a+l), (a+i)); //backtrack
}
}
}
/* Driver program to test above functions */
int main()
{
char str[] = "ABC";
int n = strlen(str);
permute(str, 0, n-1);
return 0;
}
Java
281
Chapter 52. Write a program to print all permutations of a given string
{
String str = "ABC";
int n = str.length();
Permutation permutation = new Permutation();
permutation.permute(str, 0, n-1);
}
/**
* permutation function
* @param str string to calculate permutation for
* @param l starting index
* @param r end index
*/
private void permute(String str, int l, int r)
{
if (l == r)
System.out.println(str);
else
{
for (int i = l; i <= r; i++)
{
str = swap(str,l,i);
permute(str, l+1, r);
str = swap(str,l,i);
}
}
}
/**
* Swap Characters at position
* @param a string value
* @param i position 1
* @param j position 2
* @return swapped string
*/
public String swap(String a, int i, int j)
{
char temp;
char[] charArray = a.toCharArray();
temp = charArray[i] ;
charArray[i] = charArray[j];
charArray[j] = temp;
return String.valueOf(charArray);
}
}
// This code is contributed by Mihir Joshi
282
Chapter 52. Write a program to print all permutations of a given string
Python
C#
283
Chapter 52. Write a program to print all permutations of a given string
{
if (l == r)
Console.WriteLine(str);
else
{
for (int i = l; i <= r; i++)
{
str = swap(str, l, i);
permute(str, l + 1, r);
str = swap(str, l, i);
}
}
}
/**
* Swap Characters at position
* @param a string value
* @param i position 1
* @param j position 2
* @return swapped string
*/
public static String swap(String a,
int i, int j)
{
char temp;
char[] charArray = a.ToCharArray();
temp = charArray[i] ;
charArray[i] = charArray[j];
charArray[j] = temp;
string s = new string(charArray);
return s;
}
// Driver Code
public static void Main()
{
String str = "ABC";
int n = str.Length;
permute(str, 0, n-1);
}
}
// This code is contributed by mits
PHP
<?php
// PHP program to print all
284
Chapter 52. Write a program to print all permutations of a given string
285
Chapter 52. Write a program to print all permutations of a given string
?>
Output:
ABC
ACB
BAC
BCA
CBA
CAB
Source
https://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/
286
Chapter 53
Given an array A[] and a number x, check for pair in A[] with sum as x - GeeksforGeeks
Write a program that, given an array A[] of n numbers and another number x, determines
whether or not there exist two elements in S whose sum is exactly x.
METHOD 1 (Use Sorting)
Algorithm :
Time Complexity: Depends on what sorting algorithm we use. If we use Merge Sort or
Heap Sort then (-)(nlogn) in worst case. If we use Quick Sort then O(n^2) in worst case.
Auxiliary Space : Again, depends on sorting algorithm. For example auxiliary space is
O(n) for merge sort and O(1) for Heap Sort.
287
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
Example :
Let Array be {1, 4, 45, 6, 10, -8} and sum to find be 16
Sort the array
A = {-8, 1, 4, 6, 10, 45}
Initialize l = 0, r = 5
A[l] + A[r] ( -8 + 45) > 16 => decrement r. Now r = 10
A[l] + A[r] ( -8 + 10) increment l. Now l = 1
A[l] + A[r] ( 1 + 10) increment l. Now l = 2
A[l] + A[r] ( 4 + 10) increment l. Now l = 3
A[l] + A[r] ( 6 + 10) == 16 => Found candidates (return 1)
Note: If there are more than one pair having the given sum then this algorithm reports only
one. Can be easily extended for this though.
Below is the implementation of the above approach.
C
288
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
}
/* FOLLOWING FUNCTIONS ARE ONLY FOR SORTING
PURPOSE */
void exchange(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int partition(int A[], int si, int ei)
{
int x = A[ei];
int i = (si - 1);
int j;
for (j = si; j <= ei - 1; j++)
{
if(A[j] <= x)
{
i++;
exchange(&A[i], &A[j]);
}
}
exchange (&A[i + 1], &A[ei]);
return (i + 1);
}
/* Implementation of Quick Sort
A[] --> Array to be sorted
si --> Starting index
ei --> Ending index
*/
void quickSort(int A[], int si, int ei)
{
int pi; /* Partitioning index */
if(si < ei)
{
pi = partition(A, si, ei);
quickSort(A, si, pi - 1);
quickSort(A, pi + 1, ei);
}
}
/* Driver program to test above function */
int main()
289
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
{
int A[] = {1, 4, 45, 6, 10, -8};
int n = 16;
int arr_size = 6;
if( hasArrayTwoCandidates(A, arr_size, n))
printf("Array has two elements with given sum");
else
printf("Array doesn't have two elements with given sum");
getchar();
return 0;
}
C++
290
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
}
/* Driver program to test above function */
int main()
{
int A[] = {1, 4, 45, 6, 10, -8};
int n = 16;
int arr_size = sizeof(A) / sizeof(A[0]);
// Function calling
if(hasArrayTwoCandidates(A, arr_size, n))
cout << "Array has two elements with given sum";
else
cout << "Array doesn't have two elements with given sum";
return 0;
}
Java
291
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
r--;
}
return false;
}
// Driver code
public static void main(String args[])
{
int A[] = {1, 4, 45, 6, 10, -8};
int n = 16;
int arr_size = A.length;
// Function calling
if(hasArrayTwoCandidates(A, arr_size, n))
System.out.println("Array has two " +
"elements with given sum");
else
System.out.println("Array doesn't have " +
"two elements with given sum");
}
}
Python
292
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
C#
293
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
sort(A, 0, arr_size-1);
/* Now look for the two candidates
in the sorted array*/
l = 0;
r = arr_size-1;
while (l < r)
{
if(A[l] + A[r] == sum)
return true;
else if(A[l] + A[r] < sum)
l++;
else // A[i] + A[j] > sum
r--;
}
return false;
}
/* Below functions are only to sort the
array using QuickSort */
/* This function takes last element as pivot,
places the pivot element at its correct
position in sorted array, and places all
smaller (smaller than pivot) to left of
pivot and all greater elements to right
of pivot */
static int partition(int []arr, int low, int high)
{
int pivot = arr[high];
// index of smaller element
int i = (low-1);
for (int j = low; j <= high - 1; j++)
{
// If current element is smaller
// than or equal to pivot
if (arr[j] <= pivot)
{
i++;
// swap arr[i] and arr[j]
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
294
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
PHP
295
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
<?php
// PHP program to check if given
// array has 2 elements whose sum
// is equal to the given value
// Function to check if array has
// 2 elements whose sum is equal
// to the given value
function hasArrayTwoCandidates($A, $arr_size,
$sum)
{
$l; $r;
/* Sort the elements */
//sort($A, A + arr_size);
sort($A);
/* Now look for the two candidates
in the sorted array*/
$l = 0;
$r = $arr_size - 1;
while ($l < $r)
{
if($A[$l] + $A[$r] == $sum)
return 1;
else if($A[$l] + $A[$r] < $sum)
$l++;
else // A[i] + A[j] > sum
$r--;
}
return 0;
}
// Driver Code
$A = array (1, 4, 45, 6, 10, -8);
$n = 16;
$arr_size = sizeof($A);
// Function calling
if(hasArrayTwoCandidates($A, $arr_size, $n))
echo "Array has two elements " .
"with given sum";
else
echo "Array doesn't have two " .
"elements with given sum";
// This code is contributed by m_kit
?>
296
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
Output :
297
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
C++
Java
298
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
import java.io.*;
import java.util.HashSet;
class PairSum
{
static void printpairs(int arr[],int sum)
{
HashSet<Integer> s = new HashSet<Integer>();
for (int i=0; i<arr.length; ++i)
{
int temp = sum-arr[i];
// checking for condition
if (temp>=0 && s.contains(temp))
{
System.out.println("Pair with given sum " +
sum + " is (" + arr[i] +
", "+temp+")");
}
s.add(arr[i]);
}
}
// Main to test the above function
public static void main (String[] args)
{
int A[] = {1, 4, 45, 6, 10, 8};
int n = 16;
printpairs(A, n);
}
}
// This article is contributed by Aakash Hasija
Python
299
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
C#
300
Chapter 53. Given an array A[] and a number x, check for pair in A[] with sum as x
Output:
Source
https://www.geeksforgeeks.org/given-an-array-a-and-a-number-x-check-for-pair-in-a-with-sum-as-x/
301