diff --git a/DIRECTORY.md b/DIRECTORY.md index 56ac6b94994c..439621e390da 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -425,6 +425,7 @@ * [Climbing Stairs](dynamic_programming/climbing_stairs.py) * [Combination Sum Iv](dynamic_programming/combination_sum_iv.py) * [Edit Distance](dynamic_programming/edit_distance.py) + * [Egg Dropping](dynamic_programming/egg_dropping.py) * [Factorial](dynamic_programming/factorial.py) * [Fast Fibonacci](dynamic_programming/fast_fibonacci.py) * [Fibonacci](dynamic_programming/fibonacci.py) @@ -591,6 +592,7 @@ * [Graphs Floyd Warshall](graphs/graphs_floyd_warshall.py) * [Greedy Best First](graphs/greedy_best_first.py) * [Greedy Min Vertex Cover](graphs/greedy_min_vertex_cover.py) + * [Hopcroft Karp](graphs/hopcroft_karp.py) * [Johnson](graphs/johnson.py) * [Kahns Algorithm Long](graphs/kahns_algorithm_long.py) * [Kahns Algorithm Topo](graphs/kahns_algorithm_topo.py) diff --git a/backtracking/sodukuSolver b/backtracking/sodukuSolver new file mode 100644 index 000000000000..17206654565c --- /dev/null +++ b/backtracking/sodukuSolver @@ -0,0 +1,76 @@ +class Solution(object): + def solveSudoku(self, board): + """ + :type board: List[List[str]] + :rtype: None Do not return anything, modify board in-place instead. + """ + # Helper functions for bit manipulation + def char_to_index(ch): + return ord(ch) - ord('1') + + def index_to_char(index): + return chr(index + ord('1')) + + # Initialize bitmasks for rows, columns, and boxes + rows = [0] * 9 + cols = [0] * 9 + boxes = [0] * 9 + + # Populate bitmasks with initial board values + for r in range(9): + for c in range(9): + if board[r][c] != '.': + num = char_to_index(board[r][c]) + bit = 1 << num + rows[r] |= bit + cols[c] |= bit + boxes[(r // 3) * 3 + (c // 3)] |= bit + + # Check if placing a number is valid + def is_valid(row, col, num): + bit = 1 << num + box_index = (row // 3) * 3 + (col // 3) + return not (rows[row] & bit or cols[col] & bit or boxes[box_index] & bit) + + # Forward Checking to find the most constrained cell + def select_cell(): + min_possibilities = float('inf') + cell = None + for row in range(9): + for col in range(9): + if board[row][col] == '.': + possibilities = 0 + for num in range(9): + if is_valid(row, col, num): + possibilities += 1 + if possibilities < min_possibilities: + min_possibilities = possibilities + cell = (row, col) + return cell + + # Recursive function to solve the board + def solve(): + cell = select_cell() + if cell is None: + return True # All cells are filled + + row, col = cell + for num in range(9): + if is_valid(row, col, num): + bit = 1 << num + board[row][col] = index_to_char(num) + rows[row] |= bit + cols[col] |= bit + boxes[(row // 3) * 3 + (col // 3)] |= bit + + if solve(): + return True + + board[row][col] = '.' + rows[row] &= ~bit + cols[col] &= ~bit + boxes[(row // 3) * 3 + (col // 3)] &= ~bit + + return False + + solve()