Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

In above diagram Knight takes 3 step to reach

from (4, 5) to (1, 1) (4, 5) -> (5, 3) -> (3, 2)


-> (1, 1) as shown in diagram
Recommended: Please solve it on “PRACTICE ” first, before moving on to the solution.
This problem can be seen as shortest path in unweighted graph. Therefore we use BFS to solve this
problem. We try all 8 possible positions where a Knight can reach from its position. If reachable position is
not already visited and is inside the board, we push this state into queue with distance 1 more than its parent
state. Finally we return distance of target position, when it gets pop out from queue.
Below code implements BFS for searching through cells, where each cell contains its coordinate and
distance from starting node. In worst case, below code visits all cells of board, making worst-case time
complexity as O(N^2)

import java.util.*;

// Java program to find minimum steps to reach to


// specific cell in minimum moves by Knight
class GFG
{

// Class for storing a cell's data


static class cell
{
int x, y;
int dis;

public cell(int x, int y, int dis)


{
this.x = x;
this.y = y;
this.dis = dis;
}

// Utility method returns true if (x, y) lies


// inside Board
static boolean isInside(int x, int y, int N)
{
if (x >= 1 && x <= N && y >= 1 && y <= N)
return true;
return false;
}

// Method returns minimum step


// to reach target position
// This code contributed by Rajput-Ji

Output:
20

Detect Cycle in a Directed Graph


Given a directed graph, check whether the graph contains a cycle or not. Your function should return true if
the given graph contains at least one cycle, else return false. For example, the following graph contains three
cycles 0->2->0, 0->1->2->0 and 3->3, so your function must return true.
Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.
Depth First Traversal can be used to detect a cycle in a Graph. DFS for a connected graph produces a tree.
There is a cycle in a graph only if there is a back edge present in the graph. A back edge is an edge that is
from a node to itself (self-loop) or one of its ancestor in the tree produced by DFS. In the following graph,
there are 3 back edges, marked with a cross sign. We can observe that these 3 back edges indicate 3 cycles
present in the graph.

For a disconnected graph, we get the DFS forest as output. To detect cycle, we can check for a cycle in
individual trees by checking back edges.
To detect a back edge, we can keep track of vertices currently in recursion stack of function for DFS
traversal. If we reach a vertex that is already in the recursion stack, then there is a cycle in the tree. The edge
that connects current vertex to the vertex in the recursion stack is a back edge. We have used recStack[]
array to keep track of vertices in the recursion stack.
// A Java Program to detect cycle in a graph
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

class Graph {

private final int V;


private final List<List<Integer>> adj;

public Graph(int V)
{
this.V = V;
adj = new ArrayList<>(V);

for (int i = 0; i < V; i++)


adj.add(new LinkedList<>());
}

// This function is a variation of DFSUytil() in


// https://www.geeksforgeeks.org/archives/18212
private boolean isCyclicUtil(int i, boolean[] visited,
boolean[] recStack)
{
+ "contain cycle");
}
}

// This code is contributed by Sagar Shah.

Output:
Graph contains cycle
Time Complexity of this method is same as time complexity of DFS traversal which is O(V+E).
Detect cycle in an undirected graph
.
Given an undirected graph, how to check if there is a cycle in the graph? For example, the following graph
has a cycle 1-0-2-1.

Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

We have discussed cycle detection for directed graph. We have also discussed a union-find algorithm for
cycle detection in undirected graphs. The time complexity of the union-find algorithm is O(ELogV). Like
directed graphs, we can use DFS to detect cycle in an undirected graph in O(V+E) time. We do a DFS
traversal of the given graph. For every visited vertex ‘v’, if there is an adjacent ‘u’ such that u is already
visited and u is not parent of v, then there is a cycle in graph. If we don’t find such an adjacent for any vertex,
we say that there is no cycle. The assumption of this approach is that there are no parallel edges between
any two vertices.

// A Java Program to detect cycle in an undirected graph


import java.io.*;
import java.util.*;

// This class represents a directed graph using adjacency list


// representation
class Graph
{
private int V; // No. of vertices
private LinkedList<Integer> adj[]; // Adjacency List Represntation

// Constructor
Graph(int v) {
V = v;
adj = new LinkedList[v];
for(int i=0; i<v; ++i)
adj[i] = new LinkedList();
}

// Function to add an edge into the graph


void addEdge(int v,int w) {
adj[v].add(w);
adj[w].add(v);
}
Graph g2 = new Graph(3);
g2.addEdge(0, 1);
g2.addEdge(1, 2);
if (g2.isCyclic())
System.out.println("Graph contains cycle");
else
System.out.println("Graph doesn't contains cycle");
}
}
// This code is contributed by Aakash Hasija
Output:
Graph contains cycle
Graph doesn't contain cycle
Time Complexity: The program does a simple DFS Traversal of graph and graph is represented using
adjacency list. So the time complexity is O(V+E)

Topological Sorting
Topological sorting for Directed Acyclic Graph (DAG) is a linear ordering of vertices such that for every
directed edge uv, vertex u comes before v in the ordering. Topological Sorting for a graph is not possible if
the graph is not a DAG.
For example, a topological sorting of the following graph is “5 4 2 3 1 0”. There can be more than one
topological sorting for a graph. For example, another topological sorting of the following graph is “4 5 2 3 1 0”.
The first vertex in topological sorting is always a vertex with in-degree as 0 (a vertex with no incoming
edges).

Topological Sorting vs Depth First Traversal (DFS):


In DFS, we print a vertex and then recursively call DFS for its adjacent vertices. In topological sorting, we
need to print a vertex before its adjacent vertices. For example, in the given graph, the vertex ‘5’ should be
printed before vertex ‘0’, but unlike DFS, the vertex ‘4’ should also be printed before vertex ‘0’. So
Topological sorting is different from DFS. For example, a DFS of the shown graph is “5 2 3 1 0 4”, but it is not
a topological sorting
Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

Algorithm to find Topological Sorting:


We recommend to first see implementation of DFS here. We can modify DFS to find Topological Sorting of a
graph. In DFS, we start from a vertex, we first print it and then recursively call DFS for its adjacent vertices. In
topological sorting, we use a temporary stack. We don’t print the vertex immediately, we first recursively call
topological sorting for all its adjacent vertices, then push it to a stack. Finally, print contents of stack. Note
// one by one
for (int i = 0; i < V; i++)
if (visited[i] == false)
topologicalSortUtil(i, visited, stack);

// Print contents of stack


while (stack.empty()==false)
System.out.print(stack.pop() + " ");
}

// Driver method
public static void main(String args[])
{
// Create a graph given in the above diagram
Graph g = new Graph(6);
g.addEdge(5, 2);
g.addEdge(5, 0);
g.addEdge(4, 0);
g.addEdge(4, 1);
g.addEdge(2, 3);
g.addEdge(3, 1);

System.out.println("Following is a Topological " +


"sort of the given graph");
g.topologicalSort();
}
}
// This code is contributed by Aakash Hasija

Output:
Following is a Topological Sort of the given graph
5 4 2 3 1 0
Time Complexity: The above algorithm is simply DFS with an extra stack. So time complexity is same as
DFS which is O(V+E).
Applications:
Topological Sorting is mainly used for scheduling jobs from the given dependencies among jobs. In computer
science, applications of this type arise in instruction scheduling, ordering of formula cell evaluation when
recomputing formula values in spreadsheets, logic synthesis, determining the order of compilation tasks to
perform in makefiles, data serialization, and resolving symbol dependencies in linkers [2].

Kahn’s algorithm for Topological Sorting


Topological sorting for Directed Acyclic Graph (DAG) is a linear ordering of vertices such that for every
directed edge uv, vertex u comes before v in the ordering. Topological Sorting for a graph is not possible if
the graph is not a DAG.
For example, a topological sorting of the following graph is “5 4 2 3 1 0?. There can be more than one
topological sorting for a graph. For example, another topological sorting of the following graph is “4 5 2 0 3 1″.
The first vertex in topological sorting is always a vertex with in-degree as 0 (a vertex with no in-coming
edges).
Time Complexity: The outer for loop will be executed V number of times and the inner for loop will be
executed E number of times, Thus overall time complexity is O(V+E).
The overall time complexity of the algorithm is O(V+E)
Below is C++ implementation of above algorithm. The implementation uses method 2 discussed above for
finding indegrees.
// A Java program to print topological sorting of a graph
// using indegrees
import java.util.*;

//Class to represent a graph


class Graph
{
int V;// No. of vertices

//An Array of List which contains


//references to the Adjacency List of
//each vertex
List <Integer> adj[];
public Graph(int V)// Constructor
{
this.V = V;
adj = new ArrayList[V];
for(int i = 0; i < V; i++)
adj[i]=new ArrayList<Integer>();
}

// function to add an edge to graph


public void addEdge(int u,int v)
{
adj[u].add(v);
}
// prints a Topological Sort of the complete graph
public void topologicalSort()
{
// Create a array to store indegrees of all
// vertices. Initialize all indegrees as 0.
int indegree[] = new int[V];

// Traverse adjacency lists to fill indegrees of


// vertices. This step takes O(V+E) time
for(int i = 0; i < V; i++)
{
ArrayList<Integer> temp = (ArrayList<Integer>) adj[i];
for(int node : temp)
{
indegree[node]++;
}
}

// Create a queue and enqueue all vertices with


// indegree 0
Queue<Integer> q = new LinkedList<Integer>();
for(int i = 0;i < V; i++)
{
if(indegree[i]==0)
q.add(i);
}

// Initialize count of visited vertices


int cnt = 0;

// Create a vector to store result (A topological


Given a sorted dictionary of an alien language, find order of
characters
Given a sorted dictionary (array of words) of an alien language, find order of characters in the language.
Examples:
Input: words[] = {"baa", "abcd", "abca", "cab", "cad"}
Output: Order of characters is 'b', 'd', 'a', 'c'
Note that words are sorted and in the given language "baa"
comes before "abcd", therefore 'b' is before 'a' in output.
Similarly we can find other orders.

Input: words[] = {"caa", "aaa", "aab"}


Output: Order of characters is 'c', 'a', 'b'

Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.


The idea is to create a graph of characters and then find topological sorting of the created graph. Following
are the detailed steps.
1) Create a graph g with number of vertices equal to the size of alphabet in the given alien language. For
example, if the alphabet size is 5, then there can be 5 characters in words. Initially there are no edges in
graph.
2) Do following for every pair of adjacent words in given sorted array.
…..a) Let the current pair of words be word1 and word2. One by one compare characters of both words and
find the first mismatching characters.
…..b) Create an edge in g from mismatching character of word1 to that of word2.
3) Print topological sorting of the above created graph.
Following is the implementation of the above algorithm.
// A Java program to order of
// characters in an alien language
import java.util.*;

// Class to represent a graph


class Graph
{

// An array representing the graph as an adjacency list


private final LinkedList<Integer>[] adjacencyList;

Graph(int nVertices)
{
adjacencyList = new LinkedList[nVertices];
for (int vertexIndex = 0; vertexIndex < nVertices; vertexIndex++)
{
adjacencyList[vertexIndex] = new LinkedList<>();
}
}

// function to add an edge to graph


void addEdge(int startVertex, int endVertex)
{
adjacencyList[startVertex].add(endVertex);
}

private int getNoOfVertices()


private static void printOrder(String[] words, int alpha)
{
// Create a graph with 'aplha' edges
Graph graph = new Graph(alpha);

for (int i = 0; i < words.length - 1; i++)


{
// Take the current two words and find the first mismatching
// character
String word1 = words[i];
String word2 = words[i+1];
for (int j = 0; j < Math.min(word1.length(), word2.length()); j++)
{
// If we find a mismatching character, then add an edge
// from character of word1 to that of word2
if (word1.charAt(j) != word2.charAt(j))
{
graph.addEdge(word1.charAt(j) - 'a', word2.charAt(j)- 'a');
break;
}
}
}

// Print topological sort of the above created graph


graph.topologicalSort();
}

// Driver program to test above functions


public static void main(String[] args)
{
String[] words = {"caa", "aaa", "aab"};
printOrder(words, 3);
}
}

//Contributed by Harikrishnan Rajan

Output:
c a b
Time Complexity: The first step to create a graph takes O(n + alhpa) time where n is number of given words
and alpha is number of characters in given alphabet. The second step is also topological sorting. Note that
there would be alpha vertices and at-most (n-1) edges in the graph. The time complexity of topological
sorting is O(V+E) which is O(n + aplha) here. So overall time complexity is O(n + aplha) + O(n + aplha) which
is O(n + aplha).
Exercise:
The above code doesn’t work when the input is not valid. For example {“aba”, “bba”, “aaa”} is not valid,
because from first two words, we can deduce ‘a’ should appear before ‘b’, but from last two words, we can
deduce ‘b’ should appear before ‘a’ which is not possible. Extend the above program to handle invalid inputs
and generate the output as “Not valid”.

Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5


We have discussed Kruskal’s algorithm for Minimum Spanning Tree. Like Kruskal’s algorithm, Prim’s
algorithm is also a Greedy algorithm. It starts with an empty spanning tree. The idea is to maintain two sets of
vertices. The first set contains the vertices already included in the MST, the other set contains the vertices
not yet included. At every step, it considers all the edges that connect the two sets, and picks the minimum
weight edge from these edges. After picking the edge, it moves the other endpoint of the edge to the set
containing MST.
A group of edges that connects two set of vertices in a graph is called cut in graph theory. So, at every step
Pick the vertex with minimum key value and not already included in MST (not in mstSET). We can either pick
vertex 7 or vertex 2, let vertex 7 is picked. So mstSet now becomes {0, 1, 7}. Update the key values of
adjacent vertices of 7. The key value of vertex 6 and 8 becomes finite (1 and 7 respectively).

Pick the vertex with minimum key value and not already included in MST (not in mstSET). Vertex 6 is picked.
So mstSet now becomes {0, 1, 7, 6}. Update the key values of adjacent vertices of 6. The key value of vertex
5 and 8 are updated.

We repeat the above steps until mstSet includes all vertices of given graph. Finally, we get the following
graph.

Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.


How to implement the above algorithm?
We use a boolean array mstSet[] to represent the set of vertices included in MST. If a value mstSet[v] is true,
then vertex v is included in MST, otherwise not. Array key[] is used to store key values of all vertices. Another
array parent[] to store indexes of parent nodes in MST. The parent array is the output array which is used to
show the constructed MST.

// A Java program for Prim's Minimum Spanning Tree (MST) algorithm.


// The program is for adjacency matrix representation of the graph

import java.util.*;
// Update key value and parent index of the adjacent
// vertices of the picked vertex. Consider only those
// vertices which are not yet included in MST
for (int v = 0; v < V; v++)

// graph[u][v] is non zero only for adjacent vertices of m


// mstSet[v] is false for vertices not yet included in MST
// Update the key only if graph[u][v] is smaller than key[v]
if (graph[u][v] != 0 && mstSet[v] == false && graph[u][v] < key[v]) {
parent[v] = u;
key[v] = graph[u][v];
}
}

// print the constructed MST


printMST(parent, graph);
}

public static void main(String[] args)


{
/* Let us create the following graph
2 3
(0)--(1)--(2)
| / \ |
6| 8/ \5 |7
| / \ |
(3)-------(4)
9 */
MST t = new MST();
int graph[][] = new int[][] { { 0, 2, 0, 6, 0 },
{ 2, 0, 3, 8, 5 },
{ 0, 3, 0, 0, 7 },
{ 6, 8, 0, 0, 9 },
{ 0, 5, 7, 9, 0 } };

// Print the solution


t.primMST(graph);
}
}
// This code is contributed by Aakash Hasija

Output:
Edge Weight
0 - 1 2
1 - 2 3
0 - 3 6
1 - 4 5
Time Complexity of the above program is O(V^2). If the input graph is represented using adjacency list, then
the time complexity of Prim’s algorithm can be reduced to O(E log V) with the help of binary heap. Please
see Prim’s MST for Adjacency List Representation for more details.

The Knight’s tour problem | Backtracking-1


Backtracking is an algorithmic paradigm that tries different solutions until finds a solution that “works”.
Problems which are typically solved using backtracking technique have following property in common. These
problems can only be solved by trying every possible configuration and each configuration is tried only once.

You might also like