diff --git a/NQueens.java b/NQueens.java new file mode 100644 index 00000000..2fb3f203 --- /dev/null +++ b/NQueens.java @@ -0,0 +1,99 @@ +/* +Time Complexity : O(N!. 3N) where N is the size of the board. 3N for validating the placement at each cell +Space Complexity : O(N) on the recursion stack +Did this code successfully run on Leetcode : +Any problem you faced while coding this : +Approach : + +We need to place N queens on the board. Need to check if the placement is valid. If yes, add the placement string to +result list. We can create a NXN boolean board, where true represent a queen is placed and false represents otherwise. + We can place one queen row by row, so for a row, we place the queen from 0 to jth column. Once the queen is placed + successfully, we call the recursion on the next row. Once all rows are done, we need to convert the board into list +of strings and add to result. + +Before placing a queen, we check its column, its top right and top left diagonals, if a queen is already placed there, +we return false. + +Finally, if all queens are placed correctly, we create a string with Q and . from true and false state of the board. + +*/ +import java.util.ArrayList; +import java.util.List; + +public class NQueens { + public List> solveNQueens(int n) { + List> result = new ArrayList<>(); + // Create board to keep the state + boolean[][] board = new boolean[n][n]; + placeQueens(board, 0, result); + return result; + } + + private void placeQueens(boolean[][] board,int i, List> result) { + int rows = board.length; + // If we reach the row size, we have a valid solution and add it to result + if(i == rows){ + List solution = convertBoardToString(board); + result.add(solution); + return; + } + + for (int j = 0; j < board[0].length; j++) { + if(isValidPlacement(board, i, j)){ + board[i][j] = true; + placeQueens(board, i+1, result); + // backtrack + board[i][j] = false; + } + + } + + } + + boolean isValidPlacement(boolean[][] board, int i, int j){ + int tempi = i; + int tempj = j; + // check top left diagonal + while(tempi >= 0 && tempj >= 0){ + if(board[tempi][tempj]) return false; + tempi--; + tempj--; + } + tempi = i; + tempj = j; + + // check all values in the same column + while(tempi >= 0){ + if(board[tempi][tempj]) return false; + tempi--; + } + + tempi = i; + tempj = j; + // check for queen in the top right diagonal + while(tempi >= 0 && tempj < board[0].length){ + if(board[tempi][tempj]) return false; + tempi--; + tempj++; + } + + return true; + } + + private List convertBoardToString(boolean[][] board) { + List solution = new ArrayList<>(); + for (int i = 0; i < board.length; i++) { + StringBuilder temp = new StringBuilder(); + for (int j = 0; j < board[0].length; j++) { + // convert board state to list of strings + if(board[i][j]){ + temp.append("Q"); + }else { + temp.append("."); + } + } + solution.add(temp.toString()); + } + return solution; + } +} diff --git a/WordSearch.java b/WordSearch.java new file mode 100644 index 00000000..2728c5c6 --- /dev/null +++ b/WordSearch.java @@ -0,0 +1,56 @@ +/* +Time Complexity : O(M.N.3^L) where M and N are the rows and cols in the board. At each cell, there are 3 neighbors that need +to be explored. +Space Complexity : O(L) in the recursion stack, the entire length of the word +Did this code successfully run on Leetcode : Yes +Any problem you faced while coding this : No +Approach : + +We need to perform dfs on each cell that matches the first char of the word. To mark the cell visited, we can change the char +to "#". Once a path is explored we need to back track as that particular character can appear in the word later, so our path need +to visit the character and then un-visit it. So once all the children are explored for a character in the board, will unmark +by restoring its previous value. + +*/ +public class WordSearch { + int[][] directions = {{0,1}, {1,0}, {-1,0}, {0,-1}}; + public boolean exist(char[][] board, String word) { + int rows = board.length; + int cols = board[0].length; + + for(int i = 0; i < rows; i++){ + for(int j = 0; j < cols; j++){ + if(board[i][j] == word.charAt(0)){ + if(wordExist(board, i, j, word, 0)){ + return true; + } + } + } + } + return false; + } + + public boolean wordExist(char[][] board, int i, int j, String word,int index){ + int rows = board.length; + int cols = board[0].length; + // If we reach end of the given word, we return true as all the characters in the word are matched + if(index == word.length()) return true; + + // If we reach the board boundaries, we return false. We have explored all cells in the direction. + if(i < 0 || j < 0 || i == rows || j == cols) return false; + if(board[i][j] != word.charAt(index)) return false; + + char temp = board[i][j]; + board[i][j] = '#'; + for(int [] dirs: directions){ + int newRow = dirs[0] + i; + int newCol = dirs[1] + j; + if(wordExist(board, newRow, newCol, word, index+1)){ + return true; + } + } + // backtrack + board[i][j] = temp; + return false; + } +}