LeetCode 036 Valid Sudoku

题目


Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.

The Sudoku board could be partially filled, where empty cells are filled with the character '.'.


A partially filled sudoku which is valid.

判断一个数独是不是合理的。

思路


碰到此类实际应用问题,不用慌,直接根据题目的意思来。按照规则有三条,那么我们的检查就按照这三条来做:

a every row都不能有重复数字

b every col 都不能有重复数字

c every 9格不能有重复数字

另外,要注意输入的横和列是否为9;是否除了1-9和. ,还有其他不合理的数字?


代码


public class Solution {
    public boolean isValidSudoku(char[][] board) {
       if(board==null){
			  return false;
		  }
		  int n= board.length;
		  if(n!=9){
			  return false;
		  }
		  if(board[0].length!=9){
			  return false;
		  }
		  HashMap<Character,Integer> rule = new HashMap<Character,Integer>();
		  for(int k=1;k<=9;k++){
			  rule.put((char)('0'+k),0);


		  }
<span style="white-space:pre">		</span>//判断列
		  for(int j=0;j<9;j++){
			  for(int k=1;k<=9;k++){
				  rule.put((char)('0'+k),0);
			  }

			  for(int i=0;i<9;i++){

				  if(board[i][j]=='.'){
					  continue;
				  }

				  if(!rule.containsKey(board[i][j])){

					  return false;
				  }
				  else{
					  if(rule.get(board[i][j])==1){
						  return false;
					  }
					  else{
						  rule.put(board[i][j],1);
					  }
				  }
			  }
		  }
		  //判断行
		  for(int j=0;j<9;j++){
			  for(int k=1;k<=9;k++){
				  rule.put((char)('0'+k),0);
			  }
			  for(int i=0;i<9;i++){
				  if(board[j][i]=='.'){
					  continue;
				  }
				  if(!rule.containsKey(board[j][i])){
					  return false;
				  }
				  else{
					  if(rule.get(board[j][i])==1){
						  return false;
					  }
					  else{
						  rule.put(board[j][i],1);
					  }
				  }
			  }
		  }
		//判断9宫格
		  for(int i=0;i<3;i++){
			  for(int j=0;j<3;j++){
				  for(int k=1;k<=9;k++){
					  rule.put((char)('0'+k),0);
				  }
				  int starti= i*3;
				  int startj= j*3;
				  for(int ii=0;ii<9;ii++){
					  if(board[starti+ii/3][startj+ii%3]=='.'){
						  continue;
					  }
					  if(!rule.containsKey(board[starti+ii/3][startj+ii%3])){
						  return false;
					  }
					  else{
						  if(rule.get(board[starti+ii/3][startj+ii%3])==1){
							  return false;
						  }
						  else{
							  rule.put(board[starti+ii/3][startj+ii%3],1);
						  }
					  }
				  }

			  }
		  }
		  return true;
	  }
}


修改


虽然通过了,但是整整90行啊,不满意,继续美化代码!

1 是否需要使用HashMap,其实一个数组就可以解决问题!下坐标还正好对应数字,何乐而不为?改!

2 每次 判断部分其实都一样,弄成一个函数(模块化),改!

3 结果修改后代码60行出头,而且整洁清楚多了!

public class Solution {
    public boolean isValidSudoku(char[][] board) {
     if(board==null){
			  return false;
		  }
		  int n= board.length;
		  if(n!=9){
			  return false;
		  }
		  if(board[0].length!=9){
			  return false;
		  }
		  //列
		  for(int j=0;j<9;j++){
			  boolean[] flag = new boolean[10];
			  for(int i=0;i<9;i++){
				  char c = board[i][j];
				  if(!markFlag(flag,c)){
					  return false;
				  }
			  }
		  }
		 //行
		  for(int i=0;i<9;i++){
			  boolean[] flag = new boolean[10];
			  for(int j=0;j<9;j++){
				  char c = board[i][j];
				  if(!markFlag(flag,c)){
					  return false;
				  }
			  }
		  }
		//九宫格
		  for(int i=0;i<3;i++){
			  for(int j=0;j<3;j++){
				  boolean[] flag = new boolean[10];
				  for(int ii=0;ii<9;ii++){
					  char c = board[i*3+ii/3][j*3+ii%3];
					  if(!markFlag(flag,c)){
						  return false;
					  }
				  }
			  }
		  }
		  return true;
	  }
	  //比较函数,包括a比较. b比较数字越界 c 比较重复
	  public boolean markFlag(boolean[] flag, char c){
		  if(c=='.'){
			  return true;
		  }
		  int index=c-'0';
		  if(index>9||index<=0){
			  return false;
		  }
		  if(flag[index]){
			  return false;
		  }
		  flag[index]=true;
		  return true;
	  }
}



15.3.25不用判断错误的字符,要注意检查列的时候,竖直检查先:

public class Solution {
    public boolean isValidSudoku(char[][] board) {
        if(board == null || board.length!= 9 || board[0].length!=9){
            return false;
        }
        
        
        for(int i=0;i<9;i++){
            boolean[] row = new boolean[10];
            for(int j=0;j<9;j++){
                char cur = board[i][j];
                if(cur == '.'){
                    continue;
                }
                else if(row[cur-'0']){
                    return false;
                }
                else{
                    row[cur-'0']=true;;
                }
            }
        }
        
        for(int i=0;i<9;i++){
            boolean[] col = new boolean[10];
            for(int j=0;j<9;j++){
                char cur = board[j][i];
                if(cur =='.'){
                    continue;
                }
                else if(col[cur-'0']){
                    return false;
                }
                else{
                    col[cur-'0']=true;
                }
            }
        }
        
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                boolean[] sq = new boolean[10];
                for(int k = 3*i;k<3*i+3;k++){
                    for(int p = 3*j;p<3*j+3;p++){
                        char cur = board[k][p];
                        if(cur == '.'){
                            continue;
                        }
                        else if(sq[cur-'0']){
                            return false;
                        }
                        else{
                            sq[cur-'0']=true;
                        }
                    }
                }
                
                
            }
        }
        
        return true;
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值