Problem: Hamiltonian Cycle
A Hamiltonian Cycle or Circuit in a graph G is a cycle that visits each vertex of G exactly once and returns to the starting vertex.
If a graph has a Hamiltonian cycle, it's a Hamiltonian graph; otherwise, it's non-Hamiltonian.
Finding a Hamiltonian cycle is an NP-complete problem, meaning there's no known efficient solution for all graph types, but solutions exist for smaller or specific types.
The Hamiltonian Cycle problem has applications in logistics, network design, and computer science.
Given an undirected graph, the task is to determine if it contains a Hamiltonian cycle. If found, print the path; otherwise, print "Solution does not exist".

Sample Input: N=5, adjMat[][] = [[0, 1, 0, 1, 0], [1, 0, 1, 1, 1], [0, 1, 0, 0, 1], [1, 1, 0, 0, 1], [0, 1, 1, 1, 0]]
Sample Output: [0, 1, 2, 4, 3, 0]

Solution (java):
import java.util.ArrayList;
import java.util.List;

public class InfobayAI {
    
    // Check if it's valid to place vertex at current position
    private static boolean isSafe(int vertex, int[][] adjMat, 
                                    List<Integer> path, int pos) {
        
        // The vertex must be adjacent to the previous vertex
        if (adjMat[path.get(pos - 1)][vertex] == 0) {
            return false;
        }

        // The vertex must not already be in the path
        for (int i = 0; i < pos; i++) {
            if (path.get(i) == vertex) {
                return false;
            }
        }

        return true;
    }

    // Recursive backtracking to construct Hamiltonian Cycle
    private static boolean hamCycleUtil(int[][] adjMat, 
                                List<Integer> path, int pos, int n) {
        
        // Base case: all vertices are in the path
        if (pos == n) {
            
            // Check if there's an edge from last to first vertex
            return adjMat[path.get(pos - 1)][path.get(0)] == 1;
        }

        // Try all possible vertices as next candidate
        for (int v = 1; v < n; v++) {
            if (isSafe(v, adjMat, path, pos)) {
                
                path.set(pos, v);
                
                if (hamCycleUtil(adjMat, path, pos + 1, n)) {
                    return true;
                }

                // Backtrack if v doesn't lead to a solution
                path.set(pos, -1);
            }
        }

        return false;
    }

    // Initialize path and invoke backtracking function
    public static List<Integer> hamCycle(int[][] adjMat) {
        
        int n = adjMat.length;
        List<Integer> path = new ArrayList<>(n);
        
        for (int i = 0; i < n; i++) {
            path.add(-1);
        }

        // Start path with vertex 0
        path.set(0, 0);

        if (!hamCycleUtil(adjMat, path, 1, n)) {
            
            List<Integer> noSolution = new ArrayList<>();
            noSolution.add(-1);
            return noSolution;
        }

        return path;
    }

    // Driver Code
    public static void main(String[] args) {
        int[][] adjMat = {
            {0, 1, 0, 1, 0},
            {1, 0, 1, 1, 1},
            {0, 1, 0, 0, 1},
            {1, 1, 0, 0, 1},
            {0, 1, 1, 1, 0}
        };

        List<Integer> path = hamCycle(adjMat);

        if (path.get(0) == -1) {
            System.out.println("Solution does not Exist");
        } 
        else {
            for (int i = 0; i < path.size(); i++) {
                System.out.print(path.get(i) + " ");
            }
            System.out.print(path.get(0));
        }
    }
}