数独问题暴力搜索

       数独问题在leetcode中有36Valid Sudoku和37Sudoku Solver两道,数独规则有三条:

                1.每一行数字在1-9不能重复。

                2.每一列数字在1-9不能重复。

                3.在所属特定的3*3邻域内的数字1-9不能重复。

        37Sudoku Solver的要求是检查当前数独的合法性,采用暴力搜索对每一个格点进行检查,需要思考的是如何检查条件3的检查方法,要确定格点的3*3邻域的遍历范围也就是要确定横纵坐标的检查范围。

        对于(i,j)特定的3*3邻域为(3*(i/3):3*(i/3+1),3*(j/3):y_end=3*(j/3+1)),当然在检查的时候要剔除本身格点的值

public class ValidSudoku {

	
	public static int rows;
	public static boolean isValid(int i,int j,char[][] board)
	{
		for(int m=0;m<rows;m++ )
		{
			if(m!=i && board[i][j]==board[m][j])
				return false;
			if(m!=j && board[i][j]==board[i][m])
				return false;
		}
		int x_start=3*(i/3),x_end=3*(i/3+1);
		int y_start=3*(j/3),y_end=3*(j/3+1);
		for(int a=x_start;a<x_end;a++)
			for(int b=y_start;b<y_end;b++)
			{
				if((a==i && b==j) || board[a][b]=='.') continue;
				if(board[a][b]==board[i][j])
					return false;
			}
		return true;
	}
	
	
	
	public static boolean isValidSudoku(char[][] board) {
		rows=board.length;
		for(int i=0;i<rows;i++)
		{
			for(int j=0;j<rows;j++)
			{
				if(board[i][j]=='.')
					continue;
				else
				{
					if(!isValid(i,j,board))
						return false;
				}
			}
		}
		return true;
    }

        37Sudoku Solver的求解数独必然要依赖第一题的合法性判断,采用回溯法(递归),

        基本思路:对于当前值为"."进行1-9的尝试填充,如果合法,则填充当前数值,并对下一个值为"."的格点填充(如果下一个填充一直可以进行到最后,则返回true;如果不能一直填充下去,则将当前的格点值恢复为".");如果当前格点的1-9尝试都不合法则返回false。当然最终全部填充完并合法则要返回true。代码如下:

class Solution {
    
    public static int rows;
    
    public static boolean backtrace(char[][] board)
    {
        for(int i=0;i<rows;i++)
        {
            for(int j=0;j<rows;j++)
            {
                if(board[i][j]=='.')
                {
                    for(char s='1';s<='9';s++)
                    {
                        if(isValid(i,j,board,s))
                        {
                            board[i][j]=s;
                            if(backtrace(board))
                                return true;
                            else
                                board[i][j]='.';
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }
    
    public static boolean isValid(int i,int j,char[][] board,char c)
	{
		for(int m=0;m<rows;m++ )
		{
			if(m!=i && c==board[m][j])
				return false;
			if(m!=j && c==board[i][m])
				return false;
		}
        
		int x_start=3*(i/3),x_end=3*(i/3+1);
		int y_start=3*(j/3),y_end=3*(j/3+1);
        
		for(int a=x_start;a<x_end;a++)
			for(int b=y_start;b<y_end;b++)
			{
				if((a==i && b==j) || board[a][b]=='.') continue;
				if(board[a][b]==c)
					return false;
			}
		return true;
	}
    
    public void solveSudoku(char[][] board) {
        rows=board.length;
        backtrace(board);
    }
}


猜你喜欢

转载自blog.csdn.net/To_be_to_thought/article/details/80349198