【LeetCode每日一题】37.解数独

【LeetCode每日一题】37.解数独

37.解数独

题目来源link
算法思想:回溯法,递归;

java代码

class Solution {
    
    
private boolean[][] line = new boolean[9][9];//用于存储第i行,是否有数字j
    private boolean[][] column = new boolean[9][9];//用于存储第i列,是否有数字j
    private boolean[][][] block = new boolean[3][3][9];//用于存储第[i][j]块,是否有数字k
    private boolean vaild = false;//正确答案之后的回溯条件;
    private List<int[]> space = new ArrayList<>();//用于存储数独中空位置的坐标
	//初始化line,column,block数组
    public void solveSudoku(char[][] board) {
    
    
        for (int i = 0; i < board.length; i++) {
    
    
			for (int j = 0; j < board.length; j++) {
    
    
				if (board[i][j] == '.') {
    
    
					space.add(new int[]{
    
    i,j});
				}
				else {
    
    //记录数独中已经存在的数字
					int dight = board[i][j]-'0';//数独[i][j]中的数字
					line[i][dight-1] = true;
					column[j][dight-1] = true;
					block[i/3][j/3][dight-1] = true;
				}
			}
		}
		//开始尝试填写数独
    	dfs(board,0);
    }

	public void dfs(char[][] board, int numSpace) {
    
    
		if (numSpace == space.size()) {
    
    //所有空格填写完成,即找到答案,则返回
			vaild = true;
			return;
		}//回溯条件:
		int[] temp = space.get(numSpace);//获取空位置[i][j]
		int i = temp[0];
		int j = temp[1];
		//回溯关键条件vaild,这里一定要判断!vaild
		//找打一个答案之后,将vaild设置成true,进行回溯
		for (int num = 0; num < 9 && !vaild; num++) {
    
    
			//判断当前空位置的行,列,块;能否填入num数字
			if (!line[i][num] && !column[j][num] && !block[i/3][j/3][num]) {
    
    
				//尝试填入num;将num相关行,列,块,设置成true
				line[i][num] = true;
				column[j][num] = true;
				block[i/3][j/3][num] = true;
				board[i][j] = (char) ('1' + num);//填入数字num;
				dfs(board, numSpace+1);//向下尝试,尝试下一个空位置;
				//dfs返回后包含两种情形:
				//1.已经找到了答案,此时vaild=true;不再进行for循环;继续回溯;
				//2.没有找到了答案,此时vaild=false;再进行for循环;继续尝试;
				line[i][num] = false;
				column[j][num] = false;
				block[i/3][j/3][num] = false;
				//无论以上何种情形,都将进行行,列,块的设置false;所以最后line,column,block数组没有变化
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_39457586/article/details/108604097