算法leetcode|37. 解数独(rust重拳出击)

Posted 二当家的白帽子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法leetcode|37. 解数独(rust重拳出击)相关的知识,希望对你有一定的参考价值。


文章目录


37. 解数独:

编写一个程序,通过填充空格来解决数独问题。

数独的解法需 遵循如下规则:

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

数独部分空格内已填入了数字,空白格用 '.' 表示。

样例 1:

输入:
	board = [["5","3",".",".","7",".",".",".","."]
			,["6",".",".","1","9","5",".",".","."]
			,[".","9","8",".",".",".",".","6","."]
			,["8",".",".",".","6",".",".",".","3"]
			,["4",".",".","8",".","3",".",".","1"]
			,["7",".",".",".","2",".",".",".","6"]
			,[".","6",".",".",".",".","2","8","."]
			,[".",".",".","4","1","9",".",".","5"]
			,[".",".",".",".","8",".",".","7","9"]]
	
输出:
	[["5","3","4","6","7","8","9","1","2"]
	,["6","7","2","1","9","5","3","4","8"]
	,["1","9","8","3","4","2","5","6","7"]
	,["8","5","9","7","6","1","4","2","3"]
	,["4","2","6","8","5","3","7","9","1"]
	,["7","1","3","9","2","4","8","5","6"]
	,["9","6","1","5","3","7","2","8","4"]
	,["2","8","7","4","1","9","6","3","5"]
	,["3","4","5","2","8","6","1","7","9"]]
	
解释:
	输入的数独如上图所示,唯一有效的解决方案如下所示:

提示:

  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字或者 '.'
  • 题目数据 保证 输入数独仅有一个解

分析:

  • 面对这道算法题目,二当家的陷入了沉思。
  • 主要是如何存储行,列,以及3*3宫内出现过的值。
  • 方法很多,集合,整形数组,布尔数组都可以,只有1-9,一共9个数,最优化的空间方式应该是仅仅用一个整形,然后用位运算。

题解:

rust

impl Solution 
    pub fn solve_sudoku(board: &mut Vec<Vec<char>>) 
        let mut line = vec![vec![false; 9]; 9];
        let mut column = vec![vec![false; 9]; 9];
        let mut block = vec![vec![vec![false; 9]; 3]; 3];
        let mut spaces = Vec::new();

        (0..9).for_each(|i| 
            (0..9).for_each(|j| 
                if board[i][j] == '.' 
                    spaces.push((i, j));
                 else 
                    let digit = board[i][j].to_digit(10).unwrap() as usize - 1;
                    line[i][digit] = true;
                    column[j][digit] = true;
                    block[i / 3][j / 3][digit] = true;
                
            );
        );

        fn dfs(board: &mut Vec<Vec<char>>, spaces: &Vec<(usize, usize)>, line: &mut Vec<Vec<bool>>, column: &mut Vec<Vec<bool>>, block: &mut Vec<Vec<Vec<bool>>>, pos: usize) -> bool 
            if pos == spaces.len() 
                return true;
            

            let (i, j) = spaces[pos];
            for digit in 0..9 
                if !line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit] 
                    line[i][digit] = true;
                    column[j][digit] = true;
                    block[i / 3][j / 3][digit] = true;
                    board[i][j] = (digit as u8 + b'1') as char;
                    if dfs(board, spaces, line, column, block, pos + 1) 
                        return true;
                    
                    line[i][digit] = false;
                    column[j][digit] = false;
                    block[i / 3][j / 3][digit] = false;
                
            

            return false;
        

        dfs(board, &mut spaces, &mut line, &mut column, &mut block, 0);
    


go

func solveSudoku(board [][]byte)  
    var line, column [9][9]bool
	var block [3][3][9]bool
	var spaces [][2]int

	for i := 0; i < 9; i++ 
		for j := 0; j < 9; j++ 
			b := board[i][j]
			if b == '.' 
				spaces = append(spaces, [2]inti, j)
			 else 
				digit := b - '1'
				line[i][digit] = true
				column[j][digit] = true
				block[i/3][j/3][digit] = true
			
		
	

	var dfs func(int) bool
	dfs = func(pos int) bool 
		if pos == len(spaces) 
			return true
		
		i, j := spaces[pos][0], spaces[pos][1]
		for digit := byte(0); digit < 9; digit++ 
			if !line[i][digit] && !column[j][digit] && !block[i/3][j/3][digit] 
				line[i][digit] = true
				column[j][digit] = true
				block[i/3][j/3][digit] = true
				board[i][j] = digit + '1'
				if dfs(pos + 1) 
					return true
				
				line[i][digit] = false
				column[j][digit] = false
				block[i/3][j/3][digit] = false
			
		
		return false
	

	dfs(0)


c++

class Solution 
private:
    bool dfs(vector<vector<char>> &board, vector<pair<int, int>> &spaces, bool line[9][9], bool column[9][9], bool block[3][3][9], int pos) 
        if (pos == spaces.size()) 
            return true;
        

        auto [i, j] = spaces[pos];
        for (int digit = 0; digit < 9; ++digit) 
            if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit]) 
                line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
                board[i][j] = digit + '1';
                if (dfs(board, spaces, line, column, block, pos + 1)) 
                    return true;
                
                line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;
            
        

        return false;
    
public:
    void solveSudoku(vector<vector<char>>& board) 
        bool line[9][9];
        bool column[9][9];
        bool block[3][3][9];
        vector<pair<int, int>> spaces;

        memset(line, false, sizeof(line));
        memset(column, false, sizeof(column));
        memset(block, false, sizeof(block));

        for (int i = 0; i < 9; ++i) 
            for (int j = 0; j < 9; ++j) 
                if (board[i][j] == '.') 
                    spaces.emplace_back(i, j);
                
                else 
                    int digit = board[i][j] - '1';
                    line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
                
            
        
        
        dfs(board, spaces, line, column, block, 0);
    
;

c

bool dfs(char **board, int *spaces[81], int spacesSize, bool line[9][9], bool column[9][9], bool block[3][3][9], int pos) 
    if (pos == spacesSize) 
        return true;
    

    int i = spaces[pos][0], j = spaces[pos][1];
    for (int digit = 0; digit < 9; ++digit) 
        if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit]) 
            line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
            board[i][j] = digit + '1';
            if (dfs(board, spaces, spacesSize, line, column, block, pos + 1)) 
                return true;
            
            line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;
        
    

    return false;


void solveSudoku(char **board, int boardSize, int *boardColSize) 
    bool line[9][9];
    bool column[9][9];
    bool block[3][3][9];
    int *spaces[81];
    int spacesSize = 0;
    memset(line, 0, sizeof(line));
    memset(column, 0, sizeof(column));
    memset(block, 0, sizeof(block));

    for (int i = 0; i < 9; ++i) 
        for (int j = 0; j < 9; ++j) 
            if (board[i][j] == '.') 
                spaces[spacesSize] = malloc(sizeof(int) * 2);
                spaces[spacesSize][0] = i;
                spaces[spacesSize++][1] = j;
             else 
                int digit = board[i][j] - '1';
                line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
            
        
    

    dfs(board, spaces, spacesSize, line, column, block, 0);


python

class Solution:
    def solveSudoku(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """

        def dfs(pos: int) -> bool:
            if pos == len(spaces):
                return True
            i, j = spaces[pos]
            for digit in range(9)以上是关于算法leetcode|37. 解数独(rust重拳出击)的主要内容,如果未能解决你的问题,请参考以下文章

Python描述 LeetCode 37. 解数独

算法系列之回溯算法IVleetcode51. N皇后和leetcode37. 解数独

算法leetcode|36. 有效的数独(rust重拳出击)

LeetCode 37.解数独

leetcode——37.解数独

LeetCode-37.解数独