diff --git a/51. N-Queens.py b/51. N-Queens.py new file mode 100644 index 00000000..2bed33e2 --- /dev/null +++ b/51. N-Queens.py @@ -0,0 +1,60 @@ +# Time: O(N!) - O(n) to go throught the board and O(n) to create the board as well. Then N! for all the possible arrangements for a particular queen. i.e. for the first queen we have n options, for the second we have n-2 options and so on. +# Space: O(N^2) - for the board + +# Question: To place n queens on an n x n chessboard such that no two queens threaten each other. Return all distinct solutions to the n-queens puzzle. + +# At first we initialize the board with all False values, indicating no queens are placed initially. +# then we call the backtrack function starting from the first row (row 0). +# The backtrack function will try to place a queen in each column of the current row +# But first we need to check if it's safe to place it there using the isSafe function. If it's safe, we mark that position as True (indicating a queen is placed) and recursively call backtrack for the next row. After exploring that path, we backtrack by marking that position as False again, allowing us to explore other possibilities. +# the base case is when row equals n, it means we've successfully placed queens in all rows, and we construct the board configuration and add it to the result list. +# The isSafe function just check the column above the current position, the diagonal left and the diagonal right to ensure that no other queen is threatening the current position. +# At the end we the return the result. +class Solution: + def solveNQueens(self, n: int) -> List[List[str]]: + res = [] + board = [[False for _ in range(n)]for _ in range(n)] + self.backtrack(board,0,res,n) + return res + def backtrack(self,board,row,res,n): + # base case + if row == n: + path = [] + for i in range(n): + rw_str = '' + for j in range(n): + if board[i][j]: rw_str += 'Q' + else: rw_str += '.' + path.append(rw_str) + res.append(path) + return + + # Logic + for c in range(n): + if self.isSafe(board,row,c): + # action + board[row][c] = True + # recurse + self.backtrack(board,row+1,res,n) + # backtrack + board[row][c] = False + + def isSafe(self,board,rw,cl): + # column up + for i in range(rw-1,-1,-1): + if board[i][cl]: return False + + # diagonal left + i,j = rw, cl + while i >= 0 and j >= 0: + if board[i][j]: return False + i -= 1 + j -= 1 + + # diagonal right + i,j = rw, cl + while i >= 0 and j < len(board): + if board[i][j]: return False + i -= 1 + j += 1 + return True \ No newline at end of file diff --git a/79. Word Search.py b/79. Word Search.py new file mode 100644 index 00000000..9db88e66 --- /dev/null +++ b/79. Word Search.py @@ -0,0 +1,34 @@ +# Time: O(m*n*3^L) where L is the lenght of the word and we have 3 options to move in each step as we mark visited. +# Space: O(L) - for the recursion stack and the path taken. + +# Question: Given an m x n grid of characters board and a string word, return true if word exists in the grid. + +# We loop on the given matrix and for each character in the cell we call the isWord function. +# The isWord function checks if the word exists starting from the current position. If not we return False +# And if the current character matches the word's current index, we mark it as visited and call the isWord function for all 4 directions and incrementing the idx. +# We go till the end and if idx == len(word) we return True and if it goes out of bounds we return False and even if any of the calls return False by not matching with the character the if True condition doesn't pass and we keep on returning False. +# i.e If any of the calls return True, we return True. If not we backtrack and mark the cell as unvisited and return False. + +class Solution: + def exist(self, board: List[List[str]], word: str) -> bool: + m, n = len(board), len(board[0]) + direc = [[1,0],[0,1],[-1,0],[0,-1]] + + for i in range(m): + for j in range(n): + found = self.isWord(board,word,0,i,j,m,n,direc) + if found: return found + return False + + def isWord(self,board,word,idx,row,col,m,n,direc): + if idx == len(word): return True + if not (0 <= row < m and 0 <= col < n): return False + + if board[row][col] == word[idx]: + board[row][col] = '#' + for r,c in direc: + nr = r + row + nc = c + col + if self.isWord(board,word,idx+1,nr,nc,m,n,direc): return True + board[row][col] = word[idx] + return False