LeetCode 37. 解数独 java实现 个人算法之旅

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

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

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

空白格用 '.' 表示。

一个数独。

答案被标成红色。

Note:

  • 给定的数独序列只包含数字 1-9 和字符 '.' 。
  • 你可以假设给定的数独只有唯一解。
  • 给定数独永远是 9x9 形式的。

解题思路

使用boolean二维数组来记录行、列、3*3小宫格。

给已经存在的数字记录为true

DFS:遍历完全部的行返回true。

从1开始填充数字

class Solution {
    public void solveSudoku(char[][] board) {
      //记录某行的,某位数字是否已经摆放
      boolean[][] row = new boolean[9][10];
      //记录某一列,某位数字是否被摆放
      boolean[][] col = new boolean[9][10];
      //记录某3*3宫格内,某位数字是否被摆放
      boolean[][] block = new boolean[9][10];
      //给已经存在的数字记录为true
      for(int i = 0; i < 9; i++){
        for(int j = 0; j < 9; j++){
         if(board[i][j] != '.'){
          int num = board[i][j] - '0';
          row[i][num] = true;
          col[j][num] = true;
          block[i / 3 * 3 + j / 3][num] = true;           
         }
        }
      }
      dfs(board,row,col,block,0,0);//回溯
    }
  public boolean dfs(char[][] board,boolean[][] row, boolean[][] col,boolean[][] block,int i,int j){
    while(board[i][j] != '.'){
      if(++j >= 9){//遍历完行的这一列,遍历下一行
        i++;
        j=0;
      }
      if(i >= 9){//遍历全部的行,返回true
        return true;
      }
    }
    for(int num = 1; num <=9; num++){//num为该数组里面的数字,假设从1开始填充数字
      int blockIndex= i / 3 * 3 + j / 3;
      if(!row[i][num] && !col[j][num] && !block[blockIndex][num]){//如果当前的数字不被包含在已经存在的数字里,则进行递归
        board[i][j] = (char)('0' + num);//把num变成char字符
        row[i][num] = true;
        col[j][num] = true;
        block[blockIndex][num] = true;//表示该数字添加入已经存在数组里
        if(dfs(board,row,col,block,i,j)){
          return true;
        }else{
          //回溯
          row[i][num] = false;
          col[j][num] = false;
          block[i / 3 * 3 + j / 3][num] = false;
          board[i][j] = '.';
        }
      }
    }
    return false;
  }
}

猜你喜欢

转载自blog.csdn.net/qq_38765867/article/details/88376037