diff --git a/N-Queens.java b/N-Queens.java new file mode 100644 index 00000000..2e93c0d3 --- /dev/null +++ b/N-Queens.java @@ -0,0 +1,67 @@ +// Time Complexity : O(n!) +// Space Complexity : O(n^2) for the board and O(n) for recursive stack +// Did this code successfully run on Leetcode : yes +// Any problem you faced while coding this : no + +// Your code here along with comments explaining your approach +/* +Initialize a board first of boolean matrix where we can construct the expected output as 'Q' and '.' whenever +cell has true & false values respectively.But, to identify if we can place a queen in a cell and mark it as true +or not, we need to check if its valid position or not.So, we maintain 3 boolean arrays to check the rules for same +column, diagonal, and anti-diagonal violations. We do a row recursion checking each column iteratively to identify +any violations and marking the cell as true.For diagonal violation, the sum of row and column value are same and +for anti diagonal violation, the difference row and column are same, we add an offset of n value for easy check. + */ +class Solution { + List> result; + boolean[][] board; + boolean[] colSet; + boolean[] diagSet; + boolean[] antiDiagSet; + public List> solveNQueens(int n) { + this.result = new ArrayList<>(); + this.board = new boolean[n][n]; + this.colSet = new boolean[2*n]; + this.diagSet = new boolean[2*n]; + this.antiDiagSet = new boolean[2*n]; + helper(0, n); + return result; + } + + private void helper(int row, int n) { + if(row == n) { + List temp = new ArrayList<>(); + for(int i = 0 ; i < n ; i++) { + StringBuilder sb = new StringBuilder(); + for(int j = 0 ; j < n ; j++) { + if(board[i][j]) { + sb.append("Q"); + } else { + sb.append("."); + } + } + temp.add(sb.toString()); + } + result.add(temp); + } + + for(int col = 0 ; col < n ; col++) { + int diagIndex = row + col; + int antiDiagIndex = row - col + n; + if(!colSet[col] && !diagSet[diagIndex] && !antiDiagSet[antiDiagIndex]) { + colSet[col] = true; + diagSet[diagIndex] = true; + antiDiagSet[antiDiagIndex] = true; + + board[row][col] = true; + helper(row + 1, n); + board[row][col] = false; + + colSet[col] = false; + diagSet[diagIndex] = false; + antiDiagSet[antiDiagIndex] = false; + + } + } + } +} \ No newline at end of file diff --git a/WordSearch.java b/WordSearch.java new file mode 100644 index 00000000..94a478e4 --- /dev/null +++ b/WordSearch.java @@ -0,0 +1,74 @@ +// Time Complexity : O(m * n * 4^L) where L is length of the word +// Space Complexity : O(L) recursive stack space of length of the word +// Did this code successfully run on Leetcode : yes +// Any problem you faced while coding this : no + +// Your code here along with comments explaining your approach +/* +The idea is to first identify the position of the word's first letter in the board and then leverage helper dfs +method to recursively traverse in all 4 directions to check if we are able to find next letters of the word in +the traversal. At any point, if we dont find or boundaries are not met, we return false. If we reach the end of +the length of the word, it means we found the word and return true.It is important to backtrack by visit and unvisit +if a direction doesnt lead us as required. Also, to optimize, we perform a frequency check of number of times a +character is appearing in the board vs word, if at any time, the count doesnt match, we return false at the start +itself. + */ +class Solution { + int m, n; + int[][] dirs; + public boolean exist(char[][] board, String word) { + this.m = board.length; + this.n = board[0].length; + this.dirs = new int[][]{{0, -1}, {-1, 0}, {0, 1}, {1,0}}; + int[] wordCount = new int[128]; + + for(int i = 0 ; i < m ; i++) { + for(int j = 0 ; j < n ; j++) { + char ch = board[i][j]; + wordCount[ch]++; + } + } + + for(int i = 0 ; i < word.length() ; i++) { + char ch = word.charAt(i); + wordCount[ch]--; + if(wordCount[ch] < 0) + return false; + } + + + + for(int i = 0 ; i < m ; i++) { + for(int j = 0 ; j < n ; j++) { + if(board[i][j] == word.charAt(0)) { + if(dfs(board, word, i, j, 0)) + return true; + } + + } + } + return false; + } + + private boolean dfs(char[][] board, String word, int i, int j, int index) { + if(index == word.length()) + return true; + + if(i < 0 || j < 0 || i == m || j == n) + return false; + + if(board[i][j] != word.charAt(index)) + return false; + + board[i][j] = '#'; + + for(int[] dir : dirs) { + int newRow = dir[0] + i; + int newCol = dir[1] + j; + if(dfs(board, word, newRow, newCol, index + 1)) + return true; + } + board[i][j] = word.charAt(index); + return false; + } +} \ No newline at end of file