Showing posts with label Java programs. Show all posts
Showing posts with label Java programs. Show all posts

Monday, December 1, 2025

Coin Change - Min Number of Coins Needed - Java Program

In this article we'll see how to write a Java program for the coin change problem, which states that "Given an array of coins storing coins of different denominations and an integer sum representing an amount. Find the minimum number of coins needed to make that sum. If that amount of money cannot be made up by any combination of the coins, return -1."

Any coin can be used any number of times.

For example-

1. Input: int coins[] = {9, 6, 5, 1}, sum = 101
Output: 12
How: 9 (10 times) + 6 + 5

2. Input: int coins[] = {1, 2, 5}, sum = 11
Output: 3
How: 5 + 5 + 1

3. Input: int coins[] = {2}, sum = 0
Output: 0

The "coin change" problem is a good example of dynamic programming as you can break this problem into smaller overlapping sub-problems and you can also store the result of those subproblems (memoization) to avoid redundant calculations.

Coin change problem Java Program

The program for finding the minimum number of coins that add to the given sum can be written using

  1. Recursion without any optimization.
  2. You can add memoization with recursion to make it faster this is also called top-down approach in dynamic programming.
  3. You can also use bottom-up approach also known as tabular form. In bottom-up approach you try to solve the sub-problems first and use their solutions to arrive at solutions to bigger sub-problems.

We'll write java programs for all these three approaches here.

1. Using recursion

Here the approach is, if for the selected coin, sum - coin >= 0, i.e. coin can be used to get the sum then we have to recursively call the method with the rest of the amount (sum-coin). You also need to ensure that you take the minimum of current count and the result of adding selected coin to count.
count = Math.min(count,  res+1);

Here is the complete Java program with the recursive method.

public class MinCoinSum {
  public static void main(String[] args) {
    int coins[] = {9, 6, 5, 1};
    int sum = 10;
    
    int c = minCoinsNeeded(coins, sum);
    System.out.println("Coins needed- " c);			
  }  
  private static int minCoinsNeeded(int[] coins, int sum) {
    if(sum == 0) {
      return 0;
    }
    int count = Integer.MAX_VALUE;
    int res = 0;
    for(int coin : coins) {
      
      if(sum - coin >= 0) {
        res = minCoinsNeeded(coins, sum-coin);				
        if(res != -1) {
          // if coin needed; that is include 
          // scenario (res+1) otherwise you go with count
          count = Math.min(count,  res+1);	
        }
      }
    }
    return (count == Integer.MAX_VALUE) ? -1 : count;
  }
}

Output

Coins needed- 2

Time and space complexity with this approach

With this approach each recursive call tries all coin denominations. If amount is n and the number of coins is c then the time complexity is O(cn)

Recursion stack depth will be n so, the space complexity is O(n).

2. Using memoization with recursion

With the above recursive method there are many repetitive calls. Memoization improves this by caching results for subproblems.

If the target amount is sum then we may need answers for all amounts from 0 up to sum in this form-

dp[i]= minimum coins required to get amount i

So, we need a 1-D array having length equal to the sum+1. This array is initialized with -1 as initial value to indicate no value is stored yet.

public class MinCoinSum {

  public static void main(String[] args) {
    int coins[] = {9, 6, 5, 1};
    int sum = 101;

    int[] dp = new int[sum+1];
    Arrays.fill(dp, -1);

    int c = minCoinsNeeded(coins, sum, dp);
    System.out.println("Coins needed- " + c);  
  }
  
  private static int minCoinsNeeded(int[] coins, int sum, int[] dp) {
    if(sum == 0) {
      return 0;
    }
    // value already stored, so return that value
    if(dp[sum] != -1) {
      return dp[sum];
    }
    int count = Integer.MAX_VALUE;
    int res = 0;
    // Go through all the coins
    for (int coin : coins) {
      // if current coin can be used to get the final amount
      if(sum - coin >= 0) {
        // recursively find the minimum coins for the remaining amount
        res = minCoinsNeeded(coins, sum - coin, dp);
        
        if(res != -1) {
          count = Math.min(count,  res+1);
        }
      }
    }
    // Store result in array
    dp[sum] = (count == Integer.MAX_VALUE) ? -1 : count;
    return dp[sum];
  }
}

Output

Coins needed- 12

Time and space complexity with this approach

If amount is n and the number of coins is c then the space complexity is O(n X c). As there are n subproblems and c checks for each subproblem.

Space needed is O(n+1) for dp array and O(n) for recursion stack so the overall space complexity is O(n).

3. With tabulation (Bottom-up) approach

With tabulation form, to write logic for minimum number of coins to get the sum, iterative logic is used not recursive which in itself is an optimization. This is also called bottom-up approach as we build solutions for all amounts starting from 0 going up all the way to given sum.

A dp array of length equal to sum+1 is needed as we go through amount 0..sum.

All entries of dp should be initialized to a large number (at least greater than the sum). The value of dp[0] is equal to 0 (zero coins needed for amount 0). The logic for solution is as given below.

  1. Iterate in an outer loop for the coins
  2. In the inner loop, for each amount i, check if using this coin improves the minimum count.
  3. Compare the scenario, if this coin is added which means dp[i – coin]+1 with current dp[i] and take the minimum.
public class MinCoinSum {

  public static void main(String[] args) {
    int coins[] = {9, 6, 5, 1};
    int sum = 101;
    
    int c1 = minNoOfCoins(coins, sum);
    System.out.println("Coins needed- " + c1);  
  }
  
  private static int minNoOfCoins(int[] coins, int sum) {
    
    int[] dp = new int[sum+1];
    // Integer.MAX_VALUE causes problem when 1 is added to it
    //Arrays.fill(dp, Integer.MAX_VALUE);
    Arrays.fill(dp, sum+1);
    dp[0] = 0;
    for(int coin : coins) {
      for(int i = coin; i <= sum; i++) {                  
      dp[i] = Math.min(dp[i], dp[i-coin] + 1);
      }
    }
    return dp[sum] > sum ? -1 : dp[sum];
  }
}

Output

Output
Coins needed- 12

Time and space complexity with this approach

If amount is n and the number of coins is c then, Outer loop runs for each coin i.e. c times. Inner loop runs for each amount up to sum i.e. n times.

Thus, the time complexity is O(n X c).

DP array of size sum + 1 is requires so the space complexity is O(n).

That's all for this topic Coin Change - Min Number of Coines Needed - Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Longest Increasing Subsequence Java Program
  2. Exponential Search Program in Java
  3. Greatest Common Divisor (GCD) of Two Numbers Java Program
  4. Detect Cycle in an Undirected Graph Using DFS - Java Program
  5. Fibonacci Series Program in Java

You may also like-

  1. Generating Getters And Setters Using Reflection in Java
  2. Producer-Consumer Java Program Using ArrayBlockingQueue
  3. How to Untar a File in Java
  4. How to Read File From The Last Line in Java
  5. How ArrayList Works Internally in Java
  6. throws Keyword in Java Exception Handling
  7. List in Python With Examples
  8. Spring Bean Life Cycle

Saturday, November 29, 2025

Longest Increasing Subsequence Java Program

In this article we'll see how to write a Java program to find the length of the longest increasing subsequence in the given array.

For example-

1. Input: nums = [10, 9, 2, 5, 3, 7, 101, 18]
Output: 4
Explanation: The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4.

2. Input: nums = [2, 0, 1, 7, 5, 9]
Output: 4
Explanation: The longest increasing subsequence is [0, 1, 7, 9] therefore the length is 4.

3. Input: nums = [4, 4, 4, 4, 4]
Output: 1

The "Longest Increasing Subsequence" problem is a good example of dynamic programming as you can break this problem into smaller overlapping sub-problems and you can also store the result of those subproblems (memoization) to avoid redundant calculations.

Longest Increasing Subsequence Java Program

The program for finding the length of longest increasing subsequence can be written using

  1. Recursion,
  2. You can add memoization with recursion to make it faster this is also called top-down approach in dynamic programming.
  3. You can also use bottom-up approach also known as tabular form. In bottom-up approach you try to solve the sub-problems first and use their solutions to arrive at solutions to bigger sub-problems.

We'll write java programs for all these three approaches here.

1. Using recursion

Let's try to understand what we need to do with an example. Suppose our elements are {9, 10, 11, 12} and i represents current element index and p represents previous element index. If i is pointing at 10 and p at 9 then we'll have to check if(arr[i] > arr[p]) for subsequence.

If condition evaluates to true then we have to do the same comparison for 10 and 11 which means incrementing i by 1 i.e. i=i+1 and assigning previous value of i to p. This is the include scenario and the length of the subsequence increases by one.

Now suppose our elements are {9, 8, 10, 11}. Again, if we check if(arr[i] > arr[p]) for subsequence it evaluates to false for arr[i] = 8 and arr[p] = 9. In this case, you won't change value of p only increment i by 1. That means arr[i]=10 and arr[p]=9. This is excluding scenario where length of the subsequence doesn't increase.

Here is the complete Java program with this approach.

public class LongestIncreasingSubsequence {
  
  public static void main(String[] args) {
     int[] arr = {10, 9, 2, 5, 3, 7, 1, 8};
     
     System.out.println(Arrays.toString(arr));
    
     System.out.println(longestSubsequence(arr, 0, -1));
  }
  
  // Using dynamic programming - recursion
  private static int longestSubsequence(int[] arr, int i, int p) {
    // exit condition
    if(i == arr.length) {
      return 0;
    }
    int max = 0;
    int include = 0;
    
    // don't take scenario- where you just increase the index
    int res = longestSubsequence(arr, i+1, p);
    
    if(p == -1 || arr[i] > arr[p]) {      
      // take scenario- where you increase index and previous index
      include = longestSubsequence(arr, i+1, i)+1;

    }
    max = Math.max(res, include);
    return max;    
  }
}

Output

[10, 9, 2, 5, 3, 7, 1, 8]
4

You call the method with i = 0 and p = -1. Then you have exclude scenario where index of the current element is incremented. Length is not increased as the element is not included in the subsequence.

In the include scenario (arr[i] > arr[p]), both p and i are changed. Length is also increased by 1 (longestSubsequence(arr, i+1, i) + 1) as element is included in the subsequence.

The variable res stores the length of LIS based on p (arr[i] is skipped) whereas variable include stores the length of LIS based on i (arr[i] is included). Since you need the maximum LIS length so you take the max of these two scenarios.

Time and space complexity with this approach

With this approach recursive method explores all subsequences of the array and the number of subsequences of an array of length n is 2n. Therefore the time complexity is O(2n).

Recursion stack depth will be n as we move forward by one index with each method call. So, the space complexity is O(n).

2. Using memoization with recursion.

With the above recursive method there are many repetitive calls with each recursive method for the same i and p value.

What if we use an array to store previous computation values and with each computation we first make a check in the array to see if that computation is already done. That's what we do with memoization approach.

Our method has two parameters i and p so we need a 2D array having row and column length same as the length of input array. This 2D array is initialized with -1 as initial value to indicate no value is stored yet.

public class LongestIncreasingSubsequence {
  
  public static void main(String[] args) {
    int[] arr = {10, 9, 2, 5, 3, 7, 1, 8};
     
    // for memoization
    int[][]dp= new int[arr.length][arr.length];
     
    for(int[] a:dp) {
      Arrays.fill(a, -1);
    }
    System.out.println(Arrays.toString(arr));
    
    System.out.println(longestSubsequenceWithM(arr, 0, -1,dp));
  }
  
  // Using dynamic programming - recursion with Memoization
  private static int longestSubsequenceWithM(int[] arr, int i, int p, int[][] dp) {
    if(i == arr.length) {
      return 0;
      
    }
    int max = 0;
    int include = 0;
    // [p+1] because p can be -1
    // Check if value is already calculated for the passed i and p,
    // if yes then return the same value
    if(dp[i][p+1] != -1) {
      return dp[i][p+1];
    }

    // don't take scenario where you just increase the index
    int res = longestSubsequenceWithM(arr, i+1, p, dp);
    if(p == -1 || arr[i] > arr[p]) {
      // take scenario where you increase index and previous index
      include = longestSubsequenceWithM(arr, i+1, i, dp)+1;            
    }
    max = Math.max(res, include);
    dp[i][p+1] = max;

    return max;
    
  }
}

Output

[10, 9, 2, 5, 3, 7, 1, 8]
4

Time and space complexity with this approach

With memoization, the time complexity becomes O(n2) as each state (i and p) is computed once, rest of the times it is extracted from the dp array.

Space needed is O(n2) for the dp array and O(n) for recursion stack. So the space complexity can be considered as O(n2).

3. With tabulation (Bottom-up) approach.

With this approach for finding the length of the longest increasing subsequence, iterative logic is used. A 1D array of size n is used to store the values where dp[i] stores the length of the longest increasing subsequence ending at index i. Initially, every dp[i] = 1 because each element is a subsequence of length 1 by itself.

There are two loops in the logic, in each iteration of the outer loop (1 <= i < array.length), arr[i] is compared with all the previous elements arr[0] to arr[i-1] in the inner loop, suppose j is used in the inner loop. Then the steps are as given below-

  1. If(arr[i] > arr[j]) – that means arr[i] can extend the increasing subsequence ending at arr[j]
  2. Take the maximum of current known LIS ending at i and what we’d get by appending arr[i] to the LIS ending at j, as the value of dp[i].

Max value in the dp array is the length of the longest increasing subsequence.

public class LongestIncreasingSubsequence {
  public static void main(String[] args) {
    int[] arr = {10, 9, 2, 5, 3, 7, 1, 8};

    System.out.println(Arrays.toString(arr));
    
    System.out.println("lis "+ findLIS(arr));
  }
  
  // Using tabulation
  public static int findLIS(int[] arr) {
    int len = arr.length;
    int[] dp = new int[len];
    Arrays.fill(dp, 1);
    int maxLis = 1;
    for(int i = 1; i < len; i++) {
      for(int j = 0; j < i; j++) {
        if(arr[i] > arr[j]) {          
          dp[i] = Math.max(dp[i], dp[j] + 1);          
        }
      }
    }
    // extract the length of LIS
    for (int length : dp) {
      maxLis = Math.max(maxLis, length);
    }

    return maxLis;
  }
}

Output

[10, 9, 2, 5, 3, 7, 1, 8]
lis 4

That's all for this topic Longest Increasing Subsequence Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Coin Change - Min Number of Coins Needed - Java Program
  2. How to Find Common Elements Between Two Arrays Java Program
  3. Two Sum - Elements in Array With Given Sum Java Program
  4. Longest Prefix Suffix Java Program

You may also like-

  1. Counting Sort Program in Java
  2. Find The First Repeated Character in a String Java Program
  3. Convert HTML to PDF in Java + Openhtmltopdf and PDFBox
  4. Java Program to Delete File And Directory Recursively
  5. Java Multithreading Interview Questions And Answers
  6. Encapsulation in Python
  7. Signal in Angular With Examples
  8. Spring Profiles With Examples

Monday, November 24, 2025

Java Program - Minimum Spanning Tree - Prim's Algorithm

In this post we'll see how to find a minimum spanning tree for a given weighted, undirected, and connected graph of V vertices and E edges using Prim's algorithm.

Minimum spanning tree

A minimum spanning tree (MST) for a given weighted, undirected graph is the subset of those edges that connect all the vertices together without forming any cycle and also has the minimum possible sum of weight.

Prim's algorithm

In the algorithm MST is built by adding edges one at a time after analysing all the adjacent edges from the vertices which are already part of the MST and choosing the edge with the minimum weight.

Prim's algorithm is termed as a greedy algorithm which starts by adding one vertex as the starting point and then finds the edge with the minimum weight from the adjacent vertices. This edge is added to the MST. Now, the spanning tree consists of two vertices. Analyse all the edges adjacent to already added vertices (ensure edge has one end in the already added vertices and other end in an unselected vertex). Then select the edge with the minimum weight and add it to the MST. Continue the process until all the vertices are added to the minimum spanning tree.

If we have a graph as given below, then let's see how Prim's algorithm tries to find the minimum spanning tree.

Graph

Let's assume that the starting vertex is A then there are 2 edges AB and AC and both have weights as 2. So, we can choose either of them let's say we go with B.

Now the tree we are constructing has two vertices A and B. Next, we need to select any of the edges from A or B which are not yet selected that means from AC, BC and BE. Algorithm choses the edge with minimum weight which is 2 meaning AC.

minimum spanning tree

Tree has three vertices now A, B and C. For next selection our choices are BC, BE, CE and CD. Out of these BC won't be considered because B and C are already added to the tree. Edge with minimum weight is CE with weight as 1.

Prims algorithm Java program

For the last vertex our choices are CD and DE. Out of that DE with weight 6 will be chosen as per Prim's algorithm.

Prim's algorithm with adjacency matrix Java Program

Since edge with minimum weight is required in each analysis of adjacent vertices so min heap created using Priority Queue is one option or you can write the logic yourself to get the minimum weight edge. Here we'll see Java programs for Prim's algorithm using both options.

How does the Prim's algorithm program works

You need three arrays-

The array named edges to store the connected edges for the vertices which are already part of the MST. This array is used to find the edge with minimum weight. Initially this array is initialized with infinite value for all the elements.

The array named mstVertices to store the constructed MST. Initialize it with -1 for all the elements in the array.

A Boolean array isInMST to keep track of the vertices which are already added to the minimum spanning tree.

Prim's algorithm starts by choosing an arbitrary vertex as starting vertex. This starting vertex is added to edges[0]. Then the process follows the following iteration.

While MST doesn't have all the vertices-

1. Find the minimum weight vertex (u), which is not already included in the MST (isInMST[i] == false).

2. Add this vertex to the MST. (add vertex to array mstVertices, set isInMST for this vertex as true)

3. Find all the adjacent vertices from the vertex u. Iterate to check all vertices v adjacent to the current vertex u. If the current edge from u to v is less than the current value of edges[v] , update edges[v] to this new lower weight.

Here is the complete Java program with the logic to create adjacency matrix and then finding the MST using Prim's algorithm.

public class Prims {
  // to store number of vertices in the graph
  private int vertices;
  private int[][] adjMatrix;

  // This array is used to pick the minimum weight edge
  // from the vertices which are not yet included in MST 
  private int[] edges;
  // Array to store the constructed MST
  private int[] mstVertices;
  // Array to check whether vertex is already included or not 
  //(true means vertex is already present)
  private boolean[] isInMST;

      
  Prims(int vertices){
    this.vertices = vertices;
    // matrix having same row and columns as vertices
    adjMatrix = new int[vertices][vertices];
    
    edges = new int[vertices];
    mstVertices = new int[vertices];
    isInMST = new boolean[vertices];
        
    for(int i = 0; i < vertices; i++){
      edges[i] = Integer.MAX_VALUE;
      mstVertices[i] = -1;
    }
    // Add the arbitrary vertex (here taken as 0) from where to 
    // start as the first element
    edges[0] = 0;

  }
  
  //For adding edges to the graph
  public void addEdge(int source, int destination, int weight) {
    if((source < 0 || source > vertices) || (destination < 0 || destination > vertices)) {
      System.out.println("Invalid edge addition");
      return;
    }
    adjMatrix[source][destination] = weight;
    // For undirected graph reverse setting also required
    adjMatrix[destination][source] = weight;
  }
  
  // For printing the adjacency matrix representing the graph
  public void printGraph() {
    for(int i = 0; i < adjMatrix.length; i++) {
      for(int j = 0; j < adjMatrix[0].length; j++) {
        System.out.print(adjMatrix[i][j] + "\t");
      }
      System.out.println();
    }
  }
  
  /** Logic for MST using Prim's start here */
  public int minEdge(){
    int min = Integer.MAX_VALUE;
    int minIndex = -1;

    for(int i = 0; i < vertices; i++){
      if(isInMST[i] == false && edges[i] < min){
        minIndex = i;
        min = edges[i];
      }
    }
    return minIndex;
  }
  
  void primMST() {
    for (int i = 0; i < vertices - 1; i++) {
        
      // Pick the minimum weight vertex
      int u = minEdge();

      isInMST[u] = true;
      
      for(int v = 0; v < vertices; v++){
        if(adjMatrix[u][v] != 0 && isInMST[v] == false 
          && adjMatrix[u][v] < edges[v]){
          edges[v] = adjMatrix[u][v];
          mstVertices[v] = u;
        }
      }
    }
  }
  
  void displayMST(){
    System.out.println("Minimum spanning tree is ");
    System.out.println("Edge \tWeight");
    for (int i = 1; i < vertices; i++){
      System.out.println(mstVertices[i] + " - " + i + "\t"
                         + adjMatrix[mstVertices[i]][i]);
    }
  }
  
  public static void main(String[] args) {
    Prims graph = new Prims(5);        
    graph.addEdge(0, 1, 2);
    graph.addEdge(0, 2, 2);
    graph.addEdge(1, 2, 4);
    graph.addEdge(1, 4, 5);
    graph.addEdge(2, 3, 7);
    graph.addEdge(2, 4, 1);
    graph.addEdge(3, 4, 6);
    graph.printGraph();
    graph.primMST();
    graph.displayMST();
  }
}

Output

0	2	2	0	0	
2	0	4	0	5	
2	4	0	7	1	
0	0	7	0	6	
0	5	1	6	0	
Minimum spanning tree is 
Edge 	Weight
0 - 1	2
0 - 2	2
4 - 3	6
2 - 4	1

Time and space complexity with this approach

In the primMST() method there is an outer loop which runs V times with in that there are two separate for loops, each running V times.

One of the inner for loop is used to select the minimum weight edge from the set of vertices not yet included in the MST. Another loop updates the edges array with the values of the adjacent vertices.

There are two separate V iterations with in the outer loop meaning O(V) + O(V) = O(2V). And there are V such oterations through outer loop so the time complexity is O(V2).

Each of the three arrays used, take O(V) space. So, the space complexity of Prim's algorithm is O(V). Note that space complexity for adjacency matrix is O(V2) if that has to be taken into consideration. In that case space complexity is O(V2).

Logic with PriorityQueue

We can replace logic written in minEdge() method by a PriorityQueue acting as a min heap. That priority queue can provide the edge with the minimum weight.

For that we'll create a class Node with fields vertex and weight and a method to compare weights so that priority queue acts as a min heap.

import java.util.PriorityQueue;

public class PrimsPQ {

  static class Node implements Comparable<Node> {
    int vertex, weight;
    Node(int v, int w) { 
      vertex = v; weight = w; 
    }

    public int compareTo(Node other) {
      return this.weight - other.weight;
    }
  }
  // to store number of vertices in the graph
  private int vertices;
  private int[][] adjMatrix;
  
  // This array is used to pick the minimum weight edge
  // from the vetices which are not yet included in MST 
  private int[] edges;
  // Array to store the constructed MST
  private int[] mstVertices;
  // Array to check whether vertex is already included or not 
  //(true means vertex is already present)
  private boolean[] isInMST;

      
  PrimsPQ(int vertices){
    this.vertices = vertices;
    // matrix having same row and columns as vertices
    adjMatrix = new int[vertices][vertices];
    
    edges = new int[vertices];
    mstVertices = new int[vertices];
    isInMST = new boolean[vertices];
    
    
    for(int i = 0; i < vertices; i++){
      edges[i] = Integer.MAX_VALUE;
      mstVertices[i] = -1;
    }
    // Add the arbitrary vertex (here taken as 0) from where to 
    // start as the first element
    edges[0] = 0;

  }
  //For adding edges to the graph
  public void addEdge(int source, int destination, int weight) {
    if((source < 0 || source > vertices) || (destination < 0 || destination > vertices)) {
      System.out.println("Invalid edge addition");
      return;
    }
    adjMatrix[source][destination] = weight;
    // For undirected graph reverse setting also required
    adjMatrix[destination][source] = weight;
  }
  
  // For printing the adjacency matrix representing the graph
  public void printGraph() {
    for(int i = 0; i < adjMatrix.length; i++) {
      for(int j = 0; j < adjMatrix[0].length; j++) {
        System.out.print(adjMatrix[i][j] + "\t");
      }
      System.out.println();
    }
  }
  
  public void primMST() {
    PriorityQueue<Node> pq = new PriorityQueue<>();
    pq.add(new Node(0, edges[0]));

    while (!pq.isEmpty()) {
      Node node = pq.poll();
      int u = node.vertex;
      isInMST[u] = true;

      for(int v = 0; v < vertices; v++){              
        if(adjMatrix[u][v] != 0 && isInMST[v] == false 
            && adjMatrix[u][v] < edges[v]){
          edges[v] = adjMatrix[u][v];
          pq.add(new Node(v, edges[v]));
          mstVertices[v] = u;
        }
      }
    }

  }
    
  void printMST(){
    System.out.println("Minimum spanning tree is ");
    System.out.println("Edge \tWeight");
    for (int i = 1; i < vertices; i++){
      System.out.println(mstVertices[i] + " - " + i + "\t"
                 + adjMatrix[mstVertices[i]][i]);
    }
  }
    
  public static void main(String[] args) {
    PrimsPQ graph = new PrimsPQ(5);
    graph.addEdge(0, 1, 2);
    graph.addEdge(0, 2, 2);
    graph.addEdge(1, 2, 4);
    graph.addEdge(1, 4, 5);
    graph.addEdge(2, 3, 7);
    graph.addEdge(2, 4, 1);
    graph.addEdge(3, 4, 6);

    graph.printGraph();
    graph.primMST();
    graph.printMST();

  }
}

Output

Output
0	2	2	0	0	
2	0	4	0	5	
2	4	0	7	1	
0	0	7	0	6	
0	5	1	6	0	
Minimum spanning tree is 
Edge 	Weight
0 - 1	2
0 - 2	2
4 - 3	6
2 - 4	1

Time and space complexity with this approach

If priority queue is used with adjacency matrix time complexity is still O(V2). Time to find the minimum edge using priority queue becomes O(log V) because of the heap. But there are still two loops running so the time complexity is O(V2).

Each of the three arrays used, take O(V) space, priority queue also takes O(V) space. So, the space complexity of Prim's algorithm is O(V). Note that space complexity for adjacency matrix is O(V2) if that has to be taken into consideration.

Prim's algorithm with adjacency list Java Program

If you are using adjacency list to represent a graph then with priority queue Prim's algorithm can be implemented as given below.

Keeping Graph creation logic in a separate class to keep the code cleaner.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Graph {
  
  static class Edge implements Comparable<Edge>{
    int destination;
    int weight;
    Edge(int destination, int weight){
      this.destination = destination;
      this.weight = weight;
    }
    @Override
    public int compareTo(Edge o) {
      // TODO Auto-generated method stub
      return Integer.compare(this.weight, o.weight);
    }
  }
  
  int vertices;
  Map<Integer, List<Edge>> adjList;
  
  Graph(int vertices){
    this.vertices = vertices;
    adjList = new HashMap<>();
  }

  void addEdge(int source, int destination, int weight) {

    adjList.computeIfAbsent(source, k->new ArrayList<>()).add(new Edge(destination, weight));
    // For undirected graph
    adjList.computeIfAbsent(destination, k->new ArrayList<>()).add(new Edge(source, weight));
  }
  
  void printGraph() {
    for(Map.Entry<Integer, List<Graph.Edge>> es :adjList.entrySet()) {
      System.out.print("Vertex " + es.getKey() + " connects to: ");
      List<Edge> list = es.getValue();
      for (Edge e : list) {
        System.out.print("[" + e.destination + " with weight " + e.weight + "] ");
      }
      System.out.println();
    }
  }

}

Prim's algorithm implementation

import java.util.Collections;
import java.util.PriorityQueue;

public class PrimsPQ {

  public void primMST(Graph graph) {
    // This array is used to pick the minimum weight edge
    // from the vetices which are not yet included in MST 
    int[] edges = new int[graph.vertices];
    // Array to store the constructed MST
    int[] mstVertices = new int[graph.vertices];
    // Array to check whether vertex is already included or not 
    //(true means vertex is already present)
    boolean[] isInMST = new boolean[graph.vertices];
    for(int i = 0; i < graph.vertices; i++){
      edges[i] = Integer.MAX_VALUE;
      mstVertices[i] = -1;
    }
    edges[0] = 0;
    PriorityQueue<Graph.Edge> pq = new PriorityQueue<Graph.Edge>();
    pq.add(new Graph.Edge(edges[0], 0));

    while (!pq.isEmpty()) {
      Graph.Edge node = pq.poll();
      int n = node.destination;
      // vertex already added
      if(isInMST[n])
        continue;
    
      isInMST[n] = true;

      for(Graph.Edge next : graph.adjList.getOrDefault(n, Collections.emptyList())) {
        int v = next.destination;
        int weight = next.weight;
        if(isInMST[v] == false && weight < edges[v]){
          edges[v] = weight;
          pq.add(new Graph.Edge(v, edges[v]));
          mstVertices[v] = n;
        }
      }
    }
    for (int i = 1; i < graph.vertices; i++)
      System.out.println(mstVertices[i] + " - " + i + "\t"
                   + edges[i]);

  }

    
  public static void main(String[] args) {
    Graph graph = new Graph(5);
    graph.addEdge(0, 1, 2);
    graph.addEdge(0, 2, 2);
    graph.addEdge(1, 2, 4);
    graph.addEdge(1, 4, 5);
    graph.addEdge(2, 3, 7);
    graph.addEdge(2, 4, 1);
    graph.addEdge(3, 4, 6);
    PrimsPQ prims = new PrimsPQ();
    graph.printGraph();
    prims.primMST(graph);
  }
}

Output

Vertex 1 connects to: [0 with weight 2] [2 with weight 4] [4 with weight 5] 
Vertex 2 connects to: [0 with weight 2] [1 with weight 4] [3 with weight 7] [4 with weight 1] 
Vertex 3 connects to: [2 with weight 7] [4 with weight 6] 
Vertex 4 connects to: [1 with weight 5] [2 with weight 1] [3 with weight 6] 
Edge 	Weight
0 - 1	2
0 - 2	2
4 - 3	6
2 - 4	1

Time and space complexity with this approach

We need to get the minimum weight vertex from the priority queue which is a O(log V) operation. That has to be done for V vertices meaning O(V log V)

We need to scan the adjacent edges for the vertex, if there are E edges then O(E log V) is the time for adding the edges to the priority queue. Thus the time complexity of Prim's algorithm, when using adjacency list and priority queue, is O((V+E)log V).

Each of the three arrays used, take O(V) space, priority queue also takes O(V) space. So, the space complexity of Prim's algorithm is O(V). Note that space complexity for adjacency list is O(V+E) if that has to be taken into consideration then the space complexity becomes O(V + E).

That's all for this topic Java Program - Minimum Spanning Tree - Prim's Algorithm. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Weighted Graph Adjacency Representation - Java Program
  2. Detect Cycle in an Undirected Graph Using BFS - Java Program
  3. Java Program - Depth First Search (DFS) Traversal For Graph
  4. Binary Tree Traversal Using Breadth First Search Java Program
  5. Queue Implementation in Java Using Array

You may also like-

  1. Java Program to Get All DB Schemas
  2. Matrix Addition Java Program
  3. Arrange Non-Negative Integers to Form Largest Number - Java Program
  4. Two Sum - Elements in Array With Given Sum Java Program
  5. matches() Method in Java String
  6. Functional Interfaces in Java
  7. Lazy Initialization in Spring Using lazy-init And @Lazy Annotation
  8. @switch in Angular With Examples

Friday, October 31, 2025

Detect Cycle in an Undirected Graph Using BFS - Java Program

In the post Detect Cycle in an Undirected Graph Using DFS - Java Program we saw how to detect a cycle in an undirected graph using DFS, in this tutorial we'll see how to write a Java program to detect a cycle in an undirected graph using breadth-first search traversal.

For example, in the following graph 0-2-3-4-0 is a cycle.

Undirected Graph Cycle

Refer post Java Program - Breadth First Search (BFS) Traversal For Graph to know in details about breadt-first search traversal of a graph.

Detecting a cycle in an undirected graph

Logic for detecting a graph with graph traversal is simple. If the vertex currently visited has already been visited that means there is a cycle in the graph.

With undirected graph, you also have to consider the fact that the connection between vertices is considered bi-directional. Edge between A and B also means an edge between B and A. This bi-directional connection should not be considered a cycle. For this reason, you also need to keep track of the parent vertex of the current vertex. When list of the adjacent vertices for the current vertex is iterated, connection back to the parent vertex should be ignored.

Cycle detection in an undirected graph using BFS - Java Program

In the Java program adjacency list is used to represent the graph. There is a visited array to keep track of the vertices which are already visited.

Program also displays the vertices which are part of the cycle, a HashMap is used to store the vertices that are part of the cycle.

BFS traversal and the cycle detection logic is in the bfs() method which uses a queue to store the adjacent vertices. You also need to keep track of the parent therefore queue adds the vertex and its parent vertex both as an array.

Queue<int[]> queue = new LinkedList<>();

While traversing the graph using breadth-first search, if you come across a vertex that is already visited but not the parent of the current vertex that means there is a cycle.

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

public class UndirectedGraphCycleBFS {
  private Map<Integer, List<Integer>> adjList;
  private int numOfVertices;

  UndirectedGraphCycleBFS(int numOfVertices){
    this.numOfVertices = numOfVertices;
    adjList = new HashMap<>();
  }
  
  // Creating adjacency list 
  public void addEdge(Integer source, Integer destination) {
    adjList.computeIfAbsent(source, k->new ArrayList<>()).add(destination);
    // For undirected graph
    adjList.computeIfAbsent(destination, k->new ArrayList<>()).add(source);
  }
  
  public void printGraph() {
    adjList.forEach((k, v) -> {
      System.out.print("Vertex " + k + " Connectes to ");
      v.forEach(e -> System.out.print(e + " "));
      System.out.println();
    });
  }
  
  /*Cycle detection logic starts here */
  public boolean isCycleDetected() {
    boolean[] visited = new boolean[numOfVertices];
    for(int i = 0; i < numOfVertices; i++) {
      if(!visited[i]) {
        if(bfs(i, visited)) {
          return true;
        }
      }
    }
    return false;
  }
  
  private boolean bfs(int currentVertex, boolean[] visited) {
    // Queue needs to add parent info for the current vertex
    Queue<int[]> queue = new LinkedList<>();
    // For starting vertex parent is -1
    queue.add(new int[]{currentVertex, -1});
    visited[currentVertex] = true;
    // This map is used to keep track of the vertices that are part of the cycle
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    map.put(currentVertex, -1);

    while(!queue.isEmpty()) {
      int[] v = queue.poll();
      int node = v[0];
      int parent = v[1];          
      for(int n : adjList.get(node)) {
              
        if(!visited[n]) {
          visited[n] = true;
          queue.add(new int[]{n, node});
          map.put(n, node);
        }else if(n != parent) { // cycle detected
          // display vertices that are part of the cycle
          printCycle(map, node, n);
          return true;
        }
      }               
    }
    return false;
  }
  
  // Helper method to print the cycle vertices
  private void printCycle(Map<Integer, Integer> parentMap, int u, int v) {
    List<Integer> cycle = new ArrayList<>();
    // Start from the node that caused the cycle detection
    cycle.add(v); 

    int current = u;
    while (current != -1 && current != v) {
      cycle.add(current);
      current = parentMap.get(current);
    }
    Collections.reverse(cycle); // Reverse to get the cycle in order
    cycle.add(parentMap.get(v)); // Add the last vertex
   
    System.out.println("Cycle vertices: " + cycle);
  }
  
  public static void main(String[] args) {
    UndirectedGraphCycleBFS graph = new UndirectedGraphCycleBFS(10);
        
    
//  graph.addEdge(0, 1);
//  graph.addEdge(0, 2);
//  graph.addEdge(0, 3);
//  graph.addEdge(0, 7); 
//  graph.addEdge(1, 4);
//  graph.addEdge(4, 5);
//  graph.addEdge(2, 5);
//  graph.addEdge(3, 6);// Creates a cycle 0-1-4-5-2-0

    
    graph.addEdge(0, 1); 
    graph.addEdge(0, 2); 
    graph.addEdge(0, 4); 
    graph.addEdge(2, 3);
    graph.addEdge(3, 4);// Creates a cycle [0, 2, 3, 4, 0]
        
    graph.printGraph(); 
    
    if(graph.isCycleDetected()) {
      System.out.println("Cycle found in the graph");
    }else {
      System.out.println("No cycle found in the graph");
    }

  }

}

Output

Vertex 0 Connectes to 1 2 4 
Vertex 1 Connectes to 0 
Vertex 2 Connectes to 0 3 
Vertex 3 Connectes to 2 4 
Vertex 4 Connectes to 0 3 
Cycle vertices: [0, 4, 3, 2]
Cycle found in the graph

Time and space complexity of cycle detection in an undirected graph using BFS

With adjacency list only adjacent vertices are stored as a list for each vertex. For each vertex, the DFS algorithm iterates over adjacency list of that vertex. In an adjacency list representation, every edge appears exactly once (directed graph) or twice (undirected graph).

Since the total time = time for vertex processing + time for scanning adjacency list for each vertex = O(V) + O(E) So, the time complexity is O(V + E).

Extra space is needed for visited array which is O(V). In recursive method, call stack may go up to the recursive depth of V in worst case so recursive call space requirement is O(V). Thus, the space complexity can be considered as O(V).

Note that storing adjacency list is also O(V + E) in case you want to include input graph too in the space complexity.

That's all for this topic Detect Cycle in an Undirected Graph Using BFS - Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Weighted Graph Adjacency Representation - Java Program
  2. Java Program to Add and Remove in Graph
  3. Java Program - Depth First Search (DFS) Traversal For Graph
  4. Find Minimum and Maximum Value Nodes in Binary Search Tree - Java Program
  5. Java Program to Create Your Own BlockingQueue

You may also like-

  1. Manacher's Algorithm to Find The Longest Palindrome - Java Program
  2. Reading Delimited File in Java Using Scanner
  3. How to Create PDF From XML Using Apache FOP
  4. Find The Maximum Element in Each Row of a Matrix Java Program
  5. Just In Time Compiler (JIT) in Java
  6. Spring MVC File Download Example
  7. Passing Query Parameters in Angular Routing
  8. Named Tuple in Python

Thursday, October 30, 2025

Detect Cycle in an Undirected Graph Using DFS - Java Program

In this post we'll see how to detect a cycle in an undirected graph using depth-first search traversal.

For example, in the following graph 0-2-3-4-0 is a cycle.

Undirected Graph Cycle

Refer post Java Program - Depth First Search (DFS) Traversal For Graph to know in details about DFS traversal of a graph.

Detecting a cycle in an undirected graph

Logic for detecting a graph with graph traversal is simple. If the vertex currently visited has already been visited that means there is a cycle in the graph.

With undirected graph, you also have to consider the fact that the connection between vertices is considered bi-directional. Edge between A and B also means an edge between B and A. This bi-directional connection should not be considered a cycle. For this reason, you also need to keep track of the parent vertex of the current vertex. When list of the adjacent vertices for the current vertex is iterated, connection back to the parent vertex should be ignored.

Cycle detection in an undirected graph - Java Program

In the Java program, adjacency list is used to represent the graph. There is a visited array to keep track of the vertices which are already visited.

Refer post Graph Adjacency Representation - Java Program to get better explanation of graph adjacency representation using adjacency matrix or adjacency list.

Program also displays the vertices which are part of the cycle, stack is used to store those vertices.

DFS traversal and the cycle detection logic is in the dfs() method which is called recursively with the adjacent vertex of the current vertex to keep going deep in the current branch. You also keep track of the parent and make a check to ignore such bi-directional connection.

if(v == parent) {			
  continue;
}

Here is the complete Java program

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
 * Undirected graph cycle detection using DFS
 */
public class UndirectedGraphCycle {
  private Map<Integer, List<Integer>> adjList;
  private int numOfVertices;
  private Stack<Integer> stack;
  UndirectedGraphCycle(int numOfVertices){
    this.numOfVertices = numOfVertices;
    adjList = new HashMap<>();
    // to keep track of the vertex for the cycle, stack is used
    // so that vertices which are visited and not part of the cycle
    // can be easily popped
    stack = new Stack<>();
  }
  
  public void addEdge(Integer source, Integer destination) {
    adjList.computeIfAbsent(source, k->new ArrayList<>()).add(destination);
    // For undirected graph
    adjList.computeIfAbsent(destination, k->new ArrayList<>()).add(source);
  }
  
  public void printGraph() {
    adjList.forEach((k, v) -> {
      System.out.print("Vertex " + k + " Connectes to ");
      v.forEach(e -> System.out.print(e + " "));
      System.out.println();
    });
  }
  
  public boolean isCycleDetected() {
    boolean[] visited = new boolean[numOfVertices];
    for(int i = 0; i < numOfVertices; i++) {
      if(!visited[i]) {
        if(dfs(i, visited, -1)) {
          return true;
        }
      }
    }
    return false;
  }
  
  // Uses DFS traversal (recursive) to detect a cycle
  private boolean dfs(int currentVertex, boolean[] visited, int parent) {
    visited[currentVertex] = true;
    stack.push(currentVertex);

    for(int v : adjList.get(currentVertex)) {
      System.out.println("Vertex " + v + " Currentv " + currentVertex);
      // undirected graph means 2 way connection so 
      // connection back to parent doesn't mean cycle
      if(v == parent) {
        
        continue;
      }
      // visited array at index is true means that vertex is already visited
      // means a cycle
      if(visited[v]) {
        /*Start - To display the vertices which are part of the cycle */
        List<Integer> cycle = new ArrayList<>();
        int startIndex = stack.indexOf(v);
        for (int i = startIndex; i < stack.size(); i++) {
          cycle.add(stack.get(i));
        }
        // Add the starting node to complete the cycle
        cycle.add(v); 
        System.out.println("Detected cycle is " + cycle);
        /*Display logic ends here comment from start to end 
         * if cycle display not needed*/
        return true;
      }
      // recursive call
      if(dfs(v, visited, currentVertex))
        return true;
    }
    // reached here means current vertex is not part of the cycle so pop it
    stack.pop();
    return false;
  }
  
  public static void main(String[] args) {
    UndirectedGraphCycle graph = new UndirectedGraphCycle(5);

    graph.addEdge(0, 1); //A-B
    //graph.addEdge(1, 2); //A-C
    graph.addEdge(0, 2); //A-C
    graph.addEdge(0, 4); //A-E
    graph.addEdge(2, 3); //C-D
    graph.addEdge(3, 4); //D-E
    
    graph.printGraph(); 
    if(graph.isCycleDetected()) {
      System.out.println("Cycle detected in the graph");
    }else {
      System.out.println("No Cycle detected in the graph");
    }
  }
}

Output

Vertex 0 Connectes to 1 2 4 
Vertex 1 Connectes to 0 
Vertex 2 Connectes to 0 3 
Vertex 3 Connectes to 2 4 
Vertex 4 Connectes to 0 3 
Detected cycle is [0, 2, 3, 4, 0]
Cycle detected in the graph

Time and space complexity of cycle detection in an undirected graph

With adjacency list only adjacent vertices are stored as a list for each vertex. For each vertex, the DFS algorithm iterates over adjacency list of that vertex. In an adjacency list representation, every edge appears exactly once (directed graph) or twice (undirected graph).

Since the total time = time for vertex processing + time for scanning adjacency list for each vertex = O(V) + O(E) So, the time complexity is O(V + E).

Extra space is needed for visited array which is O(V). In recursive method, call stack may go up to the recursive depth of V in worst case so recursive call space requirement is O(V). Thus, the space complexity can be considered as O(V).

Note that space for storing adjacency list is O(V + E), in case you want to include input graph too in the space complexity.

That's all for this topic Detect Cycle in an Undirected Graph Using DFS - Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Weighted Graph Adjacency Representation - Java Program
  2. Java Program to Add and Remove in Graph
  3. Java Program - Breadth First Search (BFS) Traversal For Graph
  4. Java Program to Delete a Node From Binary Search Tree (BST)
  5. How to Remove Elements From an Array Java Program

You may also like-

  1. Rabin-Karp Algorithm For Pattern Search - Java Program
  2. How to Sort Elements in Different Order in Java TreeSet
  3. Find Largest and Second Largest Number in Given Array Java Program
  4. How to Display Time in AM-PM Format in Java
  5. CopyOnWriteArrayList in Java With Examples
  6. Spring Boot Microservice Circuit Breaker Using Resilience4j
  7. NgNonBindable Directive in Angular
  8. Accessing Characters in Python String

Wednesday, October 29, 2025

Insertion Sort Program in Java

In this post we’ll see how to write Insertion sort program in Java. Insertion sort is good for sorting a small set of elements. Out of the three simpler sorting algorithms insertion sort, selection sort and bubble sort, insertion sort is considered a better option in most of the scenarios.

How Insertion sort works

In insertion sort you take one element at a time and the elements on the left side of the current element are considered temporarily sorted for example if you are at 4th index then elements at index 1..3 are sorted among themselves. But that is not yet the final position because any other element may have to be inserted in between these temporarily sorted elements, which means elements have to be shifted right to make place for the insertion of the element that is why the name insertion sort.

In each iteration the elements on the left of the current element are sorted and current element is compared with all the elements on its left, if it is smaller than any of these elements then it has to be inserted at that index and the elements have to be shifted right to make place for it.

For example if you have an array [5, 2, 6, 1] then you will start with 2 (2nd element) and compare it with elements on its left.

  1. In first iteration 2 is compared with 5. Since it is smaller so it has to be inserted in the place of 5 and other elements have to shifted right. Which gives the array as [2, 5, 6, 1] after first iteration.
  2. In second iteration 6 is compared with 5, since 6 is greater than 5 so nothing needs to be done. So array is still [2, 5, 6, 1].
  3. In third iteration 1 is compared with 6, since it is smaller so elements have to be shifted right which makes the array as [2, 5, 6, 6]. Note that there are more elements on the left to be compared so 1 is still not inserted as its final insertion point is still not sure at this point.
    Then 1 is compared with 5, since 1 is smaller so elements have to be shifted right which makes the array as [2, 5, 5, 6].
    Then 1 is compared with 2, since 1 is smaller so elements have to be shifted right which makes the array as [2, 2, 5, 6].
    At this point left most index is reached so we know that 1 is the smallest element so it is inserted at this index making the array as [1, 2, 5, 6].

Insertion Sort Java program

Logic for writing the insertion sort Java program is as follows-

You take one element (starting from the second element) at a time starting from left to right in the outer loop. Assign this element to a temporary variable.

In inner loop, which starts at the same index as the outer loop and moves toward left, you compare the temp variable with all the previous elements (element on the left of the current index element).

This comparison goes on till both of these conditions hold true-

  • Elements on the left side are greater than the element at the current index.
  • Leftmost element is reached.

In each iteration with in the inner loop, you also have to shift elements right by assigning the previous element to the element at the current index with in the inner loop.

public class InsertionSort {
  public static void main(String[] args) {
    int[] intArr = {47, 85, 62, 34, 7, 10, 92, 106, 2, 54};
    int[] sortedArray = insertionSort(intArr);
    System.out.println("Sorted array is- ");
    for(int num : sortedArray){
      System.out.print(num + " ");
    }
  }
    
  private static int[] insertionSort(int[] intArr){
    int temp;
    int j;
    for(int i = 1; i < intArr.length; i++){
      temp = intArr[i];
      j = i;
      while(j > 0 && intArr[j - 1] > temp){
        // shifting elements to right
        intArr[j] = intArr[j - 1];
        --j;
      }
      // insertion of the element
      intArr[j] = temp;
    }
    return intArr;
  }
}

Output

Sorted array is- 
2 7 10 34 47 54 62 85 92 106 

Time and space complexity of Insertion sort

If you have noticed in the program each time, the number of elements that are to be compared, increases in progression; in first iteration only one element has to be compared, in second iteration two elements have to be compared and so on. Which gives us the number of comparison as–

1 + 2 + 3 + ............ + N-1 = N*(N-1)/2

Which makes the Insertion sort time complexity as O(N2).

In the best case scenario, if the array is already sorted or almost sorted the while loop condition will return false making the time complexity as O(N) if it is already sorted or almost O(N) if the data is almost sorted.

Insertion sort is an in place sorting algorithm so apart from the initial array there is no auxiliary space requirement, thus the space complexity of Insertion sort is O(1).

That's all for this topic Insertion Sort Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Shell Sort Program in Java
  2. Quick Sort Program in Java
  3. Fibonacci Series Program in Java
  4. Remove Duplicate Elements From an Array in Java
  5. How to Create Password Protected Zip File in Java

You may also like-

  1. How to Run a Shell Script From Java Program
  2. Reading Delimited File in Java Using Scanner
  3. Converting Enum to String in Java
  4. Java Program to Get All DB Schemas
  5. How HashMap Internally Works in Java
  6. Race Condition in Java Multi-Threading
  7. Creating Custom Exception Class in Java
  8. Introduction to Hadoop Framework

What is In-place Algorithm

An in-place algorithm is an algorithm that doesn’t use any auxiliary space to transform the input. Though theoretically that would mean if you have an array of length n then you should use that n space itself to transform the input array but in reality you will definitely use some variables and index for array and that kind of auxiliary space is allowed for an in-place algorithm.

Examples of in-place algorithm are sorting algorithms like Bubble sort, Selection Sort, Insertion Sort that don’t require any extra space to perform sorting. That is why space complexity for these algorithms is O(1).

Merge sort, Bucket sort are examples of not in-place or out-of-place sorting algorithms.

In-place algorithm example

Let’s try to understand this auxiliary space requirement of in-place algorithm by taking an algorithm to reverse an array by using separate input and output arrays making it a not in-place algorithm.

import java.util.Arrays;

public class ReverseArray {
  public static void main(String[] args) {
    int[] intArr = {47, 85, 47, 34, 7, 10, 0, 106, 2, 54};
    reverseArray(intArr);
  }
    
  static void reverseArray(int[] intArray) {
    int n = intArray.length;
    // Using another array
    int[] tempArray = new int[n];
    for (int i = 0; i < n; i++) { 
      tempArray[n - i - 1] = intArray[i]; 
    } 
    System.out.println("Reversed Array- " + Arrays.toString(tempArray));
  }
}

But the algorithm to reverse an array can very well be written to use the same input array to reverse it. There is no need to use a separate array making it an in-place algorithm.

public class ReverseArray {
  public static void main(String[] args) {
    int[] intArr = {47, 85, 47, 34, 7, 10, 0, 106, 2, 54};
    reverseArray(intArr);
  }
    
  static void reverseArray(int[] intArray) {
    int n = intArray.length;
    for (int i = 0; i < n / 2; i++) {
      int temp = intArray[i];
      intArray[i] = intArray[n - 1 - i];
      intArray[n - 1 - i] = temp;
    }
    System.out.println("Reversed Array- " + Arrays.toString(intArray));
  }
}

That's all for this topic What is In-place Algorithm. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Shell Sort Program in Java
  2. Tree Sort in Java Using Binary Search Tree
  3. Linear Search (Sequential Search) Java Program
  4. Reverse Each Word in a String Java Program
  5. How to Remove Elements From an Array Java Program

You may also like-

  1. Converting String to Enum Type in Java
  2. How to Read File From The Last Line in Java
  3. Java Program to Get Current Date and Time
  4. Running Dos/Windows Commands From Java Program
  5. How to Loop Through a Map in Java
  6. Difference Between Abstract Class And Interface in Java
  7. Angular One-Way Data Binding Using String Interpolation
  8. Changing String Case in Python

Java Program - Breadth First Search (BFS) Traversal For Graph

In this post we'll see how to write a Java program for breadth-first search (BFS) traversal of a graph.

Graph traversal

To traverse a graph, where you try to reach all the connected vertices from the starting vertex, can be done in following ways-

  1. Depth-first search (DFS)
  2. Breadth-first search (BFS)

Breadth-first search

Contrary to DFS traversal, where algorithm works by moving away from the starting point and trying to go deep, BFS traversal works by visiting all adjacent vertices from the start vertex. Once all the adjacent vertices are exhausted then only it goes to the next level so it tries to traverse the whole breadth of the level before moving to the next level.

For example, if we have the following graph and the starting vertex is "A".

Depth First Search (DFS) Traversal of graph

From "A" you have to go to any unvisited vertex, adjacent to "A". Let's say in this case it goes to "B" then you need to visit the next adjacent vertex of current vertex "A", which will be "C" same way "D" and "E". With this order ABCDE the current level is exhausted (you have explored the full breadth of this branch) so you need to go to the next level.

You have to pick the next current vertex from the current level of "BCDE", if it is "B" then the next adjacent vertex from current vertex "B" is "F". Since there is no other adjacent vertex from "B" so you need to pick another vertex from the "BCDE" level. If it is "C" then the next adjacent vertex from current vertex "C" is "G".

That's the way you do the BFS traversal of the given graph getting the order as "ABCDEFGHIJ".

Breadth-First Search Java program

For implementing Breath-First Search graph traversal program in Java, queue data structure is used to store the vertices that are already visited. Graph may have cycles so you need to keep track of visited vertices by having an extra array of all vertices and you mark the vertices which are already visited.

Graph can be represented using adjacency matrix or by using adjacency list, which of these two ways is used to represent the graph has to be taken in account while writing Java program for BFS traversal of the graph.

Note that in this article undirected graph traversal is done.

Refer post Graph Adjacency Representation - Java Program to get better explanation of graph adjacency representation using adjacency matrix or adjacency list.

Process for Breadth-First Search traversal is as given below-

  1. From the current vertex, visit an adjacent vertex which is not yet visited, mark it as visited and add it to the queue.
  2. Keep repeating step 1 while there are still unvisited adjacent vertices from the current vertex. If there is no unvisited adjacent vertex left then remove a vertex from queue and make it the current vertex. Again, start step 1.
  3. Process is done when queue is empty.

Here is the complete BFS traversal Java program when adjacency matrix is used to represent graph.

import java.util.LinkedList;
import java.util.Queue;

public class GraphBFSAM{
  private int numOfVertices;
  private int[][] adjMatrix;
  // to store all the vertex labels
  Vertex[] vertices;
  private int temp = 0;
  
  // Vertex class as nested class
  static class Vertex{
    String label;
    // to track the visited vertices
    boolean visited;
    Vertex(String label){
      this.label = label;
    }
    public String getLabel() {
      return label;
    }
    public void setLabel(String label) {
      this.label = label;
    }
    public boolean isVisited() {
      return visited;
    }
    public void setVisited(boolean visited) {
      this.visited = visited;
    }    
  }
  
  GraphBFSAM(int numOfVertices){
    this.numOfVertices = numOfVertices;
    vertices = new Vertex[numOfVertices];
    adjMatrix = new int[numOfVertices][numOfVertices];
  }
  
  //Method to add all the graph vertices
  public void addVertex(String label) {
    vertices[temp++] = new Vertex(label);
  }
  
  public void addEdge(int source, int destination) {
    if((source < 0 || source > numOfVertices) || (destination < 0 || destination > numOfVertices)) {
      System.out.println("Invalid edge addition");
      return;
    }
    adjMatrix[source][destination] = 1;
    // For undirected graph reverse setting also required
    adjMatrix[destination][source] = 1;
  }
  
  public void printGraph() {
    for(int i = 0; i < adjMatrix.length; i++) {
      for(int j = 0; j < adjMatrix[0].length; j++) {
        System.out.print(adjMatrix[i][j] + "\t");
      }
      System.out.println();
    }
  }
  
  public void bfsTraversal(int startVertex) {
    Queue<Integer> queue = new LinkedList<Integer>();
    queue.add(startVertex);
    vertices[startVertex].setVisited(true);
    while(!queue.isEmpty()) {
      int currentVertex = queue.poll();
      System.out.print(vertices[currentVertex].getLabel() + " ");
          //Keep adding to the queue while there are still adjacent vertices
      for(int i = 0; i < adjMatrix.length; i++) {
        if(adjMatrix[currentVertex][i] == 1 && !vertices[i].isVisited()) {
          queue.add(i);
          vertices[i].setVisited(true);
        }
      }      
    }
  }
  
  public static void main(String[] args) {
    GraphBFSAM graph = new GraphBFSAM(10);
    graph.addVertex("A");
    graph.addVertex("B");
    graph.addVertex("C");
    graph.addVertex("D");
    graph.addVertex("E");
    graph.addVertex("F");
    graph.addVertex("G");
    graph.addVertex("H");
    graph.addVertex("I");
    graph.addVertex("J");
    
    graph.addEdge(0, 1); //A-B
    graph.addEdge(0, 2); //A-C
    graph.addEdge(0, 3); //A-D
    graph.addEdge(0, 4); //A-E
    graph.addEdge(1, 5); //B-F
    graph.addEdge(5, 8); //F-I
    graph.addEdge(2, 6); //C-G
    graph.addEdge(4, 7); //E-H
    graph.addEdge(7, 9); //H-J


    //graph.printGraph();
    graph.bfsTraversal(0);

  }
}

Output

A B C D E F G H I J

Important points about the program

  1. Uses a static inner class Vertex to encapsulate a vertex with fields as label to store the label of the vertex and Boolean field visited to keep track of the vertex which is already visited.
  2. Adjacency matrix is used here to represent a graph.
  3. Array named vertices is used to store the vertices of the graph and mark the vertices which are already visited.

Here is the complete Java program when adjacency list is used to represent the graph.

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;

public class GraphBFSAL {
  private Map<String, List<String>> adjList;
  // To keep track of already visited vertices
  private Set<String> visited;
  
  GraphBFSAL(){
    adjList = new HashMap<>();
    visited = new HashSet<String>();
  }
  
  public void addVertex(String v) {
    adjList.putIfAbsent(v, new ArrayList<String>());
  }
  
  public void addEdge(String source, String destination) {

    if(!adjList.containsKey(source)) {
      addVertex(source);
    }
    if(!adjList.containsKey(destination)) {
      addVertex(destination);
    }
    adjList.get(source).add(destination);
    // Reverse link also required for undirected graph
    //adjList.get(destination).add(source);
  }
  
  // Method to display graph
  public void printGraph() {
    adjList.forEach((k, v) -> {
      System.out.print("Vertex " + k+ " connects to ");
      v.forEach(e -> System.out.print(e + " "));
      System.out.println();
    });
  }
  
  public void bfsTraversal(String startVertex) {
    Queue<String> queue = new LinkedList<String>();
    queue.add(startVertex);
    visited.add(startVertex);
    while(!queue.isEmpty()) {
      String currentVertex = queue.poll();
      System.out.print(currentVertex+ " ");
      for (String s : adjList.getOrDefault(currentVertex, Collections.emptyList())) {
              if (!visited.contains(s)) {
                queue.add(s);
                visited.add(s);
              }
          }
    }
  }
  
  public static void main(String[] args) {
    GraphBFSAL graph = new GraphBFSAL();

    graph.addEdge("A", "B");
    graph.addEdge("A", "C");
    graph.addEdge("A", "D");
    graph.addEdge("A", "E");
    graph.addEdge("B", "F");
    graph.addEdge("F", "I");
    graph.addEdge("C", "G");
    graph.addEdge("E", "H");
    graph.addEdge("H", "J");
    
    //graph.printGraph();
    graph.bfsTraversal("A");
  }

}

Output

A B C D E F G H I J

Important points about the program-

  1. In the Java program Map and List collections are used to represent adjacency list.
  2. A HashSet named visited is used to store the vertices of the graph and mark the vertices which are already visited.

Time and space complexity of BFS graph traversal

If total number of vertices in the graph are V and the total number of edges are E then the time complexity is O(V2) when graph is represented as an adjacency matrix.

In adjacency matrix we have a 2D array of VXV which means while checking for neighbours of any vertex we have to scan the whole row which is O(V) time, meaning O(V2) for V vertices.

With adjacency list only adjacent vertices are stored as a list for each vertex. For each vertex, the algorithm iterates over adjacency list of that vertex. In an adjacency list representation, every edge appears exactly once (directed graph) or twice (undirected graph). Since the total time = time for vertex processing + time for scanning adjacency list for each vertex = O(V) + O(E)

So, the time complexity is O(V + E).

Auxiliary space requirement is O(V) to store visited vertices in an array or set. Queue may also end up storing V vertices (in worst case) so the space requirement is O(V) for the Queue used in the method.

Thus, the total space requirement is O(V) + O(V), discarding the constants the space complexity is O(V).

Note that adjacency list also takes O(V + E) space and adjacency matrix O(V2) space.

That's all for this topic Java Program - Breadth First Search (BFS) Traversal For Graph. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Weighted Graph Adjacency Representation - Java Program
  2. Java Program to Add and Remove in Graph
  3. Binary Tree Traversal Using Breadth First Search Java Program
  4. Linked List Implementation Java Program
  5. Ternary Search Program in Java

You may also like-

  1. Java Program to Get All DB Schemas
  2. Comparing Enum to String in Java
  3. Arrange Non-Negative Integers to Form Largest Number - Java Program
  4. Printing Numbers in Sequence Using Threads Java Program
  5. Association, Aggregation And Composition in Java
  6. Java Map getOrDefault() Method With Examples
  7. Lazy Initialization in Spring Using lazy-init And @Lazy Annotation
  8. Pure and Impure Pipes in Angular

Thursday, October 23, 2025

Java Program - Depth First Search (DFS) Traversal For Graph

In this post we'll see how to write a Java program for depth-first search (DFS) traversal of a graph.

Graph traversal

To traverse a graph, where you try to reach all the connected vertices from the starting vertex, can be done in following ways-

  1. Depth-first search (DFS)
  2. Breadth-first search (BFS)

Depth-First Search

DFS traversal tries to traverse all adjacent vertices from the start vertex, it tries to go deep while exploring a branch and backtracks to starting point once it reaches dead end to start exploring another branch.

For example, if we have the following graph and the starting vertex is "A".

Depth First Search (DFS) Traversal of graph

From "A" you have to go to any vertex, adjacent to "A". So, you see there can be multiple DFS traversal orders of a graph based on how adjacent vertex is picked. Let's say in this case it goes to "B" then you need to visit the next adjacent vertex, which will be "F" and then "I". With this order ABFI the current branch reaches a dead end (you have explored the full depth of this branch) so you need to backtrack and then pick the next adjacent vertex from starting point "A" which is "C" and so on. Final DFS traversal order is A B F I C G D E H J.

DFS traversal for graph is similar to Binary tree DFS traversal with one difference, graph may have cycles so you need to keep track of visited vertices by having an extra array of all vertices and you mark the vertices which are already visited.

Depth-First Search Java program

Depth-First Search traversal program can be written using a recursive method or by using an iterative method with a stack to keep track of traversal.

Graph can be represented using adjacency matrix or by using adjacency list, which of these two ways is used to represent the graph has to be taken in account while writing Java program for DFS traversal of the graph. Note that in this article undirected graph traversal is done.

Refer post Graph Adjacency Representation - Java Program to get better explanation of graph adjacency representation using adjacency matrix or adjacency list.

Process for DFS traversal is as given below-

For recursive logic

  1. Start from the starting vertex and mark it as visited.
  2. Recursively visit all the unvisited adjacent vertices. Mark the visited vertices.
  3. Backtrack when no unvisited adjacent vertices left.

For iterative logic

  1. Start from the starting vertex, mark it as visited and push it on the stack
  2. Visit an unvisited adjacent vertex. Mark the vertex as visited and push it on the stack
  3. Keep doing step 2 while there are adjacent vertices in that branch.
  4. When there are no unvisited adjacent vertices, backtrack by popping vertex of the stack and look for adjacent vertex in another branch.

Here is the complete Java program with both recursive and iterative methods when adjacency matrix is used to represent graph.

import java.util.Stack;

public class GraphBFS {
  private int numOfVertices;
  private int[][] adjMatrix;
  // to store all the vertex labels
  Vertex[] vertices;
  private int temp = 0;
  
  // Vertex class as nested class
  static class Vertex{
    String label;
    // to track the visited vertices
    boolean visited;
    Vertex(String label){
      this.label = label;
    }
    public String getLabel() {
      return label;
    }
    public void setLabel(String label) {
      this.label = label;
    }
    public boolean isVisited() {
      return visited;
    }
    public void setVisited(boolean visited) {
      this.visited = visited;
    }    
  }
  
  GraphBFS(int numOfVertices){
    this.numOfVertices = numOfVertices;
    vertices = new GraphBFS.Vertex[numOfVertices];
    adjMatrix = new int[numOfVertices][numOfVertices];
  }
  
  //Method to add all the graph vertices
  public void addVertex(String label) {
    vertices[temp++] = new Vertex(label);
  }
  
  public void addEdge(int source, int destination) {
    if((source < 0 || source > numOfVertices) || (destination < 0 || destination > numOfVertices)) {
      System.out.println("Invalid edge addition");
      return;
    }
    adjMatrix[source][destination] = 1;
    // For undirected graph reverse setting also required
    adjMatrix[destination][source] = 1;
  }
  
  public void printGraph() {
    for(int i = 0; i < adjMatrix.length; i++) {
      for(int j = 0; j < adjMatrix[0].length; j++) {
        System.out.print(adjMatrix[i][j] + "\t");
      }
      System.out.println();
    }
  }
  
  /* Recursive logic start */
  public void dfs(int startVertex) {
    
    System.out.println("DFS Traversal (Recursive): ");
    dfsRecursive(startVertex, vertices);
  }
  
  public void dfsRecursive(int startVertex, Vertex[] vertices) {
    vertices[startVertex].setVisited(true);
    System.out.print(vertices[startVertex].getLabel() + " ");
    for (int i = 0; i < numOfVertices; i++) {
      if (adjMatrix[startVertex][i] == 1 && !vertices[i].isVisited()) {
        dfsRecursive(i, vertices);
      }
    }
  }
  /* Recursive logic End */
  /* Iterative logic Start */
  public void dfsIterative(int startVertex) {
    boolean[] visited = new boolean[numOfVertices];
    Stack<Integer> stack = new Stack<Integer>();
    stack.push(startVertex);
    
    visited[startVertex] = true;
    
    System.out.print(vertices[startVertex].getLabel() + " ");
    while(!stack.isEmpty()) {
      int v = getNextUnvisitedVertex(stack.peek(), visited);
      if(v == -1) {
        stack.pop();
      }else {
        visited[v] = true;
        System.out.print(vertices[v].getLabel() + " ");
        //System.out.println(v);
        stack.push(v);
      }
    }
  }
  
  private int getNextUnvisitedVertex(int v, boolean[] visited) {
    for(int i = 0; i < numOfVertices; i++) {
      if(adjMatrix[v][i] == 1 && visited[i] == false) {
        return i;
      }
    }
    return -1;
  }
  /* Iterative logic End */
  
  public static void main(String[] args) {
    GraphBFS graph = new GraphBFS(10);
    graph.addVertex("A");
    graph.addVertex("B");
    graph.addVertex("C");
    graph.addVertex("D");
    graph.addVertex("E");
    graph.addVertex("F");
    graph.addVertex("G");
    graph.addVertex("H");
    graph.addVertex("I");
    graph.addVertex("J");
    
    graph.addEdge(0, 1); //A-B
    graph.addEdge(0, 2); //A-C
    graph.addEdge(0, 3); //A-D
    graph.addEdge(0, 4); //A-E
    graph.addEdge(1, 5); //B-F
    graph.addEdge(5, 8); //F-I
    graph.addEdge(2, 6); //C-G
    graph.addEdge(4, 7); //E-H
    graph.addEdge(7, 9); //H-J

    //graph.printGraph();
    graph.dfs(0);
    System.out.println("");
    System.out.println("Graph DFS Traversal (Iterative): ");
    graph.dfsIterative(0);

  }
}

Output

DFS Traversal (Recursive): 
A B F I C G D E H J 
Graph DFS Traversal (Iterative): 
A B F I C G D E H J 

Important points about the program

  1. Uses a static inner class Vertex to encapsulate a vertex with fields as label to store the label of the vertex and Boolean field visited to keep track of the vertex which is already visited.
  2. Adjacency matrix is used here to represent a graph.
  3. Array named vertices is used to store the vertices of the graph and mark the vertices which are already visited.
  4. Method named dfsRecursive() shows the recursive logic.
  5. Method named dfsIterative () shows the iterative logic.

Here is the complete Java program with both recursive and iterative methods when adjacency list is used to represent graph.

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

public class GrapdhDFSAL {

  private Map<String, List<String>> adjList;
  // To keep track of already visited vertices
  private Set<String> visited;
  
  GrapdhDFSAL(){
    adjList = new HashMap<>();
    visited = new HashSet<String>();
  }
  
  public void addVertex(String v) {
    adjList.putIfAbsent(v, new ArrayList<String>());
  }
  
  public void addEdge(String source, String destination) {

    if(!adjList.containsKey(source)) {
      addVertex(source);
    }
    if(!adjList.containsKey(destination)) {
      addVertex(destination);
    }
    adjList.get(source).add(destination);
    // Reverse link also required for undirected graph
    adjList.get(destination).add(source);
  }
  
  // Method to display graph
  public void printGraph() {
    adjList.forEach((k, v) -> {
      System.out.print("Vertex " + k+ " connects to ");
      v.forEach(e -> System.out.print(e + " "));
      System.out.println();
    });
  }
  
  /* Recursive logic start */
  public void dfs(String startVertex) {
    System.out.println("DFS Traversal (Recursive): ");
    dfsRecursive(startVertex);
  }
  
  public void dfsRecursive(String startVertex) {
    visited.add(startVertex);
    
    System.out.print(startVertex + " ");
    for (String s : adjList.getOrDefault(startVertex, Collections.emptyList())) {
      if (!visited.contains(s)) {
        dfsRecursive(s);
      }
    }
  }
  /* Recursive logic end */
  
  /* Iterative logic Start */
  public void dfsIterative(String startVertex) {
    Stack<String> stack = new Stack<String>();
    stack.push(startVertex);
    
    visited.add(startVertex);
    
    System.out.print(startVertex + " ");
    while(!stack.isEmpty()) {
      String v = getNextUnvisitedVertex(stack.peek());
      if(v.isBlank()) {
        stack.pop();
      }else {
        visited.add(v);
        System.out.print(v + " ");
        stack.push(v);
      }
    }
  }
  
  private String getNextUnvisitedVertex(String v) {
    for (String s : adjList.getOrDefault(v, Collections.emptyList())) {
      if (!visited.contains(s)) {
        return s;
      }
    }
    return "";
  }
  /* Iterative logic End */
  public static void main(String[] args) {
    GrapdhDFSAL graph = new GrapdhDFSAL();

    graph.addEdge("A", "B");
    graph.addEdge("A", "C");
    graph.addEdge("A", "D");
    graph.addEdge("A", "E");
    graph.addEdge("B", "F");
    graph.addEdge("F", "I");
    graph.addEdge("C", "G");
    graph.addEdge("E", "H");
    graph.addEdge("H", "J");
    graph.printGraph();
    // Uncomment this to run recursive method
    //System.out.println("Graph DFS Traversal (Recursive): ");
    //graph.dfs("A");
    System.out.println("Graph DFS Traversal (Iterative): ");
    graph.dfsIterative("A");

  }
}

Output

Vertex A connects to B C D E 
Vertex B connects to A F 
Vertex C connects to A G 
Vertex D connects to A 
Vertex E connects to A H 
Vertex F connects to B I 
Vertex G connects to C 
Vertex H connects to E J 
Vertex I connects to F 
Vertex J connects to H 
Graph DFS Traversal (Iterative): 
A B F I C G D E H J 

Important points about the program

  1. In the Java program, Map and List collections are used to represent adjacency list.
  2. A HashSet named visited is used to store the vertices of the graph and mark the vertices which are already visited.
  3. Method named dfsRecursive() shows the recursive logic.
  4. Method named dfsIterative () shows the iterative logic.

Time and space complexity of DFS graph traversal

If total number of vertices in the graph are V and the total number of edges are E then the time complexity is O(V2) when graph is represented as an adjacency matrix.

In adjacency matrix we have a 2D array of VXV which means while checking for neighbours of any vertex we have to scan the whole row which is O(V) meaning O(V2) for V vertices.

With adjacency list, only adjacent vertices are stored as a list for each vertex. For each vertex, the algorithm iterates over adjacency list of that vertex. In an adjacency list representation, every edge appears exactly once (directed graph) or twice (undirected graph).

Since the total time = time for vertex processing + time for scanning adjacency list for each vertex = O(V) + O(E) So, the time complexity is O(V + E).

Auxiliary space requirement is O(V) to store visited vertices in an array or set. In recursive method, call stack may go up to the recursive depth of V in worst case so recursive call space requirement is O(V).

For iterative method, stack may also end up storing V vertices (in worst case) so the space requirement is O(V) for stack used in iterative method. Thus, the total space requirement is O(V) + O(V), discarding the constants the space complexity is O(V).

That's all for this topic Java Program - Depth First Search (DFS) Traversal For Graph. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Advanced Tutorial Page


Related Topics

  1. Weighted Graph Adjacency Representation - Java Program
  2. Java Program to Add and Remove in Graph
  3. Binary Tree Traversal Using Breadth First Search Java Program
  4. Linked List Implementation Java Program
  5. Bucket Sort Program in Java

You may also like-

  1. Compress And Decompress File Using GZIP Format in Java
  2. Convert Numbers to Words Java Program
  3. Java Program - Sieve of Eratosthenes to Find Prime Numbers
  4. Convert HTML to PDF in Java + Openhtmltopdf and PDFBox
  5. How to Sort ArrayList of Custom Objects in Java
  6. Primitive Data Types in Java
  7. Spring JdbcTemplate Insert, Update And Delete Example
  8. Angular Access Control CanActivate Route Guard Example