I need to find out if given adjacency list (int[][]) is describing a strongly connected graph.
I am failing a few test cases with more than 2 nodes in the graph.
for example adjlist = new int[][] {{ 1 },{ 2 },{ 0 },}; meaning that node 0 (first in list) can connect to node 1, node 1 can connect to node 2, and node 2 can connect to node 0.
I tried this:
public boolean allDevicesConnected(int[][] adjlist) {
Boolean[] visited = new Boolean[adjlist.length];
for (int i = 0; i < adjlist.length; i++) {
for (int b = 0; b < visited.length; b++) {
visited[b] = false;
}
DFS1( adjlist, i, visited);
}
for (int j = 0; j < visited.length; j++) {
if (visited[j] == false) {
return false;
}
}
return true;
}
private static void DFS1(int[][] adjlist, int v, Boolean[] visited) {
visited[v] = true;
for (int i = 0; i < adjlist[v].length; i++) {
if (visited[i] == false) {
DFS1(adjlist, i, visited);
}
}
}
any help would be great thanks!!
Your idea to use a depth first search, while marking nodes as visited to determine if strongly connected is a good idea.
The first double for loop is not needed. If the graph is actually strongly connected, it does not matter at which node we start at.
Firstly, I notice that you are doing this in your DFS search:
visited[i] == false
and
DFS1(adjlist, i, visited);
That said, when you did this you are not checking the right node. You should be checking not the index i, but rather the actual value of the node stored at index i.
I edited your code to use this idea:
public boolean allDevicesConnected(int[][] adjlist){
boolean[] marked = new boolean[adjlist.length]; // Default is set to false
DFS_helper(0, adjlist, marked);
for(boolean b : marked)
if(b == false) return false;
return true;
}
public void DFS_helper(int node, int[][] adjlist, boolean[] marked){
marked[node] = true;
for (int i = 0; i < adjList[node].length; i++) {
int dest = adjlist[node][i];
if(marked[dest] == false)
DFS_helper(dest, adjlist, marked);
}
}
Related
example - there is an unconnected graph with vertices A - B - C - D and E - F - G. (a hyphen means that they are connected). The code below is using depth-first traversal, I need to modify it to display all connected vertices. eg:
list0: ABCD
list1: EFG
etc...
I don't understand how to implement this.
public class Graph {
private final int MAX_VERTS = 20;
private Vertex vertexList[];
private int matrix[][];
private int countV;
private StackX theStack;
// ------------------------------------------------------------
public Graph() {
vertexList = new Vertex[MAX_VERTS];
matrix = new int[MAX_VERTS][MAX_VERTS];
countV = 0;
for (int x = 0; x < MAX_VERTS; x++)
for (int y = 0; y < MAX_VERTS; y++)
matrix[x][y] = 0;
theStack = new StackX();
}
// -------------------------------------------------------------
public void addVertex(char label) {
vertexList[countV++] = new Vertex(label);
}
// -------------------------------------------------------------
public void addEdge(int x, int y) {
matrix[x][y] = 1;
matrix[y][x] = 1;
}
// -------------------------------------------------------------
public void displayVertex(int v) {
System.out.print(vertexList[v].label);
}
public void dfs() {
vertexList[0].wasVisited = true;
displayVertex(0);
theStack.push(0);
while (!theStack.isEmpty()) {
int v = getUnvisitedVertex(theStack.peek());
if (v == -1)
theStack.pop();
else
{
vertexList[v].wasVisited = true;
displayVertex(v);
theStack.push(v);
}
}
for (int j = 0; j < countV; j++)
vertexList[j].wasVisited = false;
}
// ------------------------------------------------------------
public int getUnvisitedVertex(int vertex) {
for (int j = 0; j < countV; j++)
if (matrix[vertex][j] == 1 && !vertexList[j].wasVisited) {
return j;
}
return -1;
}
}
Your DFS does not need to modified. It needs to be put inside a loop so that each pass will discover one of the lists of connected nodes that your are looking for
LOOP
Select arbitrary vertex
DFS, saving each visited vertex in list.
LOOP over visited vertices
remove from graph
LOOP END
IF all vertices removed
BREAK out of loop
Start new list
LOOP END
Output lists
This is the word search problem on leetcode. I've provided a picture below that explains it well. My approach consists of a DFS on each letter in the board (by iterating through a double for loop), I'm doing this so my dfs function can start from each letter and I can get all the different words.
I'm marking the nodes as visited by also passing in a boolean array, where the value is changed to true if I've seen that node and changed back to false if it didn't lead to a path. I think this is where I'm messing up. I'm not sure how to properly mark the nodes as visited here, and if I don't then I get an infinite loop.
When I run my program and print out the strings the dfs is building, I don't get all the possible strings. This is what I'm trying to figure out, how to get all the strings.
You can run the code in leetcode as well. Thank you!
class Solution {
public boolean exist(char[][] board, String word) {
if(board == null || word == null) {
return false;
}
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[i].length; j++) {
List<Character> tempList = new ArrayList<>();
tempList.add(board[i][j]);
boolean[][] tempBoard = new boolean[board.length][board[0].length];
if(wordExists(i, j, word, tempList, board, tempBoard)) {
return true;
}
else{
tempList.remove(tempList.size() - 1);
}
}
}
return false;
}
public static boolean wordExists(int sr, int sc, String word, List<Character> list, char[][] board, boolean[][] tempBoard) {
StringBuilder sb = new StringBuilder();
for(Character c : list) {
sb.append(c);
}
System.out.println(sb.toString());
if(word.equals(sb.toString())) {
return true;
}
final int[][] SHIFTS = {
{0,1},
{1,0},
{0,-1},
{-1,0}
};
tempBoard[sr][sc] = true;
for(int[] shift : SHIFTS) {
int row = sr + shift[0];
int col = sc + shift[1];
if(isValid(board, row, col, tempBoard)) {
list.add(board[row][col]);
if(wordExists(row, col, word, list, board, tempBoard)) {
return true;
}
tempBoard[sr][sc] = false;
list.remove(list.size() - 1);
}
}
return false;
}
public static boolean isValid(char[][] board, int row, int col, boolean[][] tempBoard) {
if(row >= 0 && row < board.length && col >= 0 && col < board[row].length && tempBoard[row][col] != true) {
return true;
}
return false;
}
}
I have a hashmap containing (point, value), I calculate the minimum value in the hashmap. Second, the retreived point I uuse it to extract corresponding values from a matrix.
then I store xmmin, and the points retreived in an arraylist
My objective is to not consider a point if it already exists in the arraylist.
I have tried this but It stucks with the first min.
Here is what I've tried
List<Integer> dataPoints = new ArrayList(); // Storing parsed elements including Xmin
HashMap<Integer, List<Integer>> clusters = new HashMap<>();
ArrayList<Integer> listt = new ArrayList<>();
List<Integer> l = new ArrayList<>(); //list of points for each xmin
while(E.size()!=dataPoints.size()) {
int xMin = getKey(E,MinX(E));
System.out.println("Xmin "+xMin);
if (!existsX(dataPoints, xMin)) {
dataPoints.add(xMin);
//checking id X exists in data points if no return close elements
for (int j = 0; j < S.getRow(xMin).length; j++) {
if (S.getEntry(xMin, j) > beta) {
l.add(j);
dataPoints.add(j);
}
}
}
Here is IfExists function
for (int k = 0; k < dataPoints.size(); k++) {
if (dataPoints.get(k) != xMin) {
return false;
}
}
return true;
}
How can I achieve that
Currently, your existsX-method contains this:
for (int k = 0; k < dataPoints.size(); k++) {
if (dataPoints.get(k) != xMin) {
return false;
}
}
return true;
Which will immediately return false at the first item that isn't the xMin, while you want to accomplish the opposite: return true as soon as xMin is found like this:
for (int k = 0; k < dataPoints.size(); k++) {
if (dataPoints.get(k) == xMin) { // != has been changed to ==
return true; // Return true as soon as we've found it
}
}
return false; // Return false if it wasn't found
Better yet however, would be to rely more on builtins that do the work for you. In this case your:
if(!existsX(dataPoints,xMin))
Can be changed to:
if(!dataPoints.contains(xMin))
So you won't need to make your own existsX-method. Here the JavaDocs for the List#contains builtin.
Your ifExists should be
for (int k = 0; k < dataPoints.size(); k++) {
if (dataPoints.get(k) == xMin) {
return true;
}
}
return false;
I am trying to implement an iterative Sudoku solver. To avoid recursion I used a stack, but I'm having problems with its management. The starting board is represented by a String array (variable 'input' in the following code) in which each element is composed of 3 numbers: the [row, col] and its value (i.e, "006" means that the element in the 1st line and 1st col is 6) and is translated into an array of int by the constructor. When I run it, I cannot get a solution, so there are probably mistakes in the nested for cycles. Any help is appreciated.
import java.util.ArrayList;
public class SudokuSolver {
private int[][] matrix = new int[9][9];
private String[] input = { "006", "073", "102", "131", "149", "217",
"235", "303", "345", "361", "378", "422", "465", "514", "521",
"548", "582", "658", "679", "743", "752", "784", "818", "883" };
private ArrayList<int[][]> stack = new ArrayList<>();
public SudokuSolver() {
// Building the board based on input array
for (int n = 0; n < input.length; ++n) {
int i = Integer.parseInt(input[n].substring(0, 1));
int j = Integer.parseInt(input[n].substring(1, 2));
int val = Integer.parseInt(input[n].substring(2, 3));
matrix[i][j] = val;
}
stack.add(matrix);
}
private boolean isSolution(int[][] cells) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if(cells[i][j] == 0)
return false;
}
}
return true;
}
private boolean isValid(int i, int j, int val, int[][] cells) {
for (int k = 0; k < 9; k++)
if (val == cells[k][j])
return false;
for (int k = 0; k < 9; k++)
if (val == cells[i][k])
return false;
return true;
}
private boolean iterativeSudokuSolver() {
int[][] current = null;
while(stack.size() > 0 && !isSolution(stack.get(0))) {
current = stack.remove(0);
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
if (current[row][col] == 0) {
for (int val = 1; val <= 9; val++) {
if (isValid(row, col, val, current)) {
current[row][col] = val;
stack.add(0, current);
break;
}
}
}
}
}
}
if (current != null && isSolution(current))
return true;
else
return false;
}
public static void main(String [] args) {
SudokuSolver sudokuSolver = new SudokuSolver();
boolean result = sudokuSolver.iterativeSudokuSolver();
if (result)
System.out.println("Sudoku solved");
else
System.out.println("Sudoku not solved");
}
}
A stack implementation by adding and removing the 0-th element of an ArrayList is a very bad idea: it forces the whole content of the array to be shifted back an forth every time. Use LinkedList or modify the end of the list.
When you add and remove the same instance of the matrix back and forth to the stack, it is still the same matrix object, even though you may call it "current" or any other name. This means that when you change something in the matrix and then remove it from your stack, the change stays there (and in every other element of your stack, which are identical links to the same object). The logic of your solution looks like it needs to store the previous state of the solution on the stack, if so - allocate a new array every time and copy the data (also not very efficient, but try starting there).
A good question has to be specific. "Why this doesn't work?" is a bad question. Fix the obvious problems first, debug, and if puzzled provide more information about the state of your program (data in, data on step #1...N, for example)
I'm attempting to write a program which solves the 8 Queens Problem using a 2 dimensional array of booleans. I will use backtracking to find the solution. I know this is not the optimal way to solve this problem, and that I should probably go for a 1D array for simplicity, but I want to solve it this way.
Right now I'm stuck on the function which is supposed to check whether a queen fits at a given coordinate. My row, column and down-right diagonal checks work, but I can't get the down-left diagonal check to work. I'm struggling to find the correct indexes of i and j (x and y) to start at, and which counter to increment/decrement for each iteration. Right now my function looks like this:
public static boolean fits(int x, int y) {
for(int i = 0; i < N; i++) {
if(board[x][i]) {
return false; // Does not fit on the row
}
}
for(int i = 0; i < N; i++) {
if(board[i][y]) {
return false; // Does not fit on the column
}
}
for(int i = Math.max(x-y, 0), j = Math.max(y-x, 0); i < N && j < N; i++, j++) {
if(board[i][j]) {
return false; // Down right diagonal issue
}
}
for(int i = Math.min(x+y, N-1), j = Math.max(N-1-x, 0); i >= 0 && j < N; i--, j++) {
if(board[i][j]) {
return false; // Supposed to check the down-left diagonal, but does not work.
}
}
return true;
}
As you can see there's a problem with the last loop here. I'd be very, very happy if someone could give me a working for-loop to check the down-left diagonal. Thanks in advance!
Edit: Here's the working code:
public class MyQueens {
static boolean[][] board;
static final int N = 8;
public static void main(String[] args) {
int p = 0;
board = new boolean[N][N];
board[1][1] = true;
System.out.println(fits(0, 2));
System.out.println(fits(2, 2));
}
public static boolean fits(int x, int y) {
for(int i = 0; i < N; i++) {
if(board[x][i]) {
return false; // Row
}
}
for(int i = 0; i < N; i++) {
if(board[i][y]) {
return false; // Column
}
}
for(int i = 0, j = 0; i < N && j < 0; i++, j++) {
if(board[i][j]) {
return false; // for right diagonal
}
}
int mirrorx = (N-1)-x;
for(int i = Math.max(mirrorx-y, 0), j = Math.max(y-mirrorx, 0); i < N && j < N; i++, j++) {
if(board[(N-1)-i][j]) {
return false;
}
}
return true;
}
}
I'm attempting to write a program which solves the 8 Queens Problem using a 2 dimensional array of booleans.
This is not the optimal representation, because you must use four loops to check if a queen can be placed or not. A much faster way of doing it is available.
For the purposes of your program, there are four things that must be free of threats in order for a queen to be placed:
A row,
A column,
An ascending diagonal, and
A descending diagonal
Each of these four things can be modeled with a separate array of booleans. There are eight rows, eight columns, fifteen ascending diagonals, and fifteen descending diagonals (including two degenerate cases of one-cell "diagonals" in the corners).
Declare four arrays row[8], col[8], asc[15] and desc[15], and use these four methods to work with it:
public static boolean fits(int r, int c) {
return !row[r] && !col[c] && !asc[r+c] && !desc[c-r+7];
}
public static void add(int r, int c) {
set(r, c, true);
}
public static void remove(int r, int c) {
set(r, c, false);
}
private static void set(int r, int c, boolean q) {
row[r] = col[c] = asc[r+c] = desc[c-r+7] = q;
}
Just flip the board horizontally and reuse the same algorithm as for the down right diagonal:
int mirrorx = (N-1)-x;
for(int i = Math.max(mirrorx-y, 0), j = Math.max(y-mirrorx, 0); i < N && j < N; i++, j++) {
if(board[(N-1)-i][j]) {
return false;
}
}
You could re-arrange it to make it more optimal.
Why don't you just use:
for(int i = 0, j = 0; i < N && j < 0; i++, j++) {
if(board[i][j]) {
return false; // for right diagonal
}
}
Similarly:
for(int i = 0, j = N-1; i < N && j >= 0; i++, j--) {
if(board[i][j]) {
return false; // for left diagonal
}
}