• 求解数独回溯算法


    实现的java代码如下(该算法只是将结果打印输出,并没有对原数组实现更改):

        //判断a[i][j]取值val是否有效
        public boolean isValid(int[][] a, int i, int j, int val){
            //判断是否跟同行冲突
            for(int j1=0;j1<9;j1++){
                if(a[i][j1]==val)
                    return false;
            }
            //判断是否跟同列冲突
            for(int i1=0;i1<9;i1++){
                if(a[i1][j]==val)
                    return false;
            }
            //找出a[i][j]所在的九宫格
            int i1 = 0, j1 = 0;
            boolean flag = true;
            for(i1=0;i1<3&&flag;i1++){
                if(!(i>=i1*3&&i<3*(i1+1)))
                    continue;
                for(j1=0;j1<3;j1++){
                    if(j>=j1*3&&j<3*(j1+1)){
                        flag = false;
                        break;
                    }
                }
            }
            i1--;
            //判断值是否跟所在九宫格冲突
            for(int i2=3*i1;i2<3*(i1+1);i2++){           
                for(int j2=3*j1;j2<3*(j1+1);j2++){
                    if(a[i2][j2]==val)
                        return false;
                }
            }
            return true;
        }
        //打印数独
        public void printMatrix(int[][] a){
            for(int i=0;i<9;i++){
                for(int j=0;j<9;j++){
                    System.out.print(a[i][j]+" ");
                }
                System.out.println();
            }
        }
        //回溯法求解数独
        public void shuDu(int[][] a, int i, int j){
            if(i==8&&j>=9){
                printMatrix(a);
                return;
            }
            if(j==9){
                j=0;
                i++;
            }
            if(a[i][j]==0){
                for(int k=1;k<=9;k++){
                    if(isValid(a,i,j,k)){
                        a[i][j] = k;
                        //向下继续找
                        shuDu(a,i,j+1);
                        //如果没有找到全部答案将a[i][j]的值恢复
                        a[i][j] = 0;
                    }
                }
            }else{
                shuDu(a,i,j+1);
            }
        }

    算法调用示例如下:

    public static void main(String[] args) {
                    Solution solu = new Solution();
            int ma1[][]={
                     {0,3,0,0,0,5,0,6,0},
                     {0,1,0,0,0,3,0,8,0},
                     {0,4,0,0,0,0,0,0,7},
                     {0,0,7,0,2,4,0,0,0},
                     {5,0,0,0,9,0,0,0,0},
                     {0,8,0,3,0,0,5,0,0},
                     {0,0,0,8,0,0,0,0,0},
                     {0,0,9,0,0,0,0,7,3},
                     {0,5,0,9,0,0,0,0,2}};
            int[][] sudoku = { 
                     {8,0,0,0,0,0,0,0,0}, 
                     {0,0,3,6,0,0,0,0,0}, 
                     {0,7,0,0,9,0,2,0,0}, 
                     {0,5,0,0,0,7,0,0,0}, 
                     {0,0,0,0,4,5,7,0,0}, 
                     {0,0,0,1,0,0,0,3,0}, 
                     {0,0,1,0,0,0,0,6,8},  
                     {0,0,8,5,0,0,0,1,0}, 
                     {0,9,0,0,0,0,4,0,0}};
            solu.shuDu(sudoku, 0, 0);
    }            

     不进行打印,实现更改数组的改进算法(数组为字符数组,可根据需要进行更改):

    public class Solution {
        //判断a[i][j]取值val是否有效
        public boolean isValid(char[][] a, int i, int j, char val){
            //判断是否跟同行冲突
            for(int j1=0;j1<9;j1++){
                if(a[i][j1]==val)
                    return false;
            }
            //判断是否跟同列冲突
            for(int i1=0;i1<9;i1++){
                if(a[i1][j]==val)
                    return false;
            }
            //找出a[i][j]所在的九宫格
            int i1 = 0, j1 = 0;
            boolean flag = true;
            for(i1=0;i1<3&&flag;i1++){
                if(!(i>=i1*3&&i<3*(i1+1)))
                    continue;
                for(j1=0;j1<3;j1++){
                    if(j>=j1*3&&j<3*(j1+1)){
                        flag = false;
                        break;
                    }
                }
            }
            i1--;
            //判断值是否跟所在九宫格冲突
            for(int i2=3*i1;i2<3*(i1+1);i2++){           
                for(int j2=3*j1;j2<3*(j1+1);j2++){
                    if(a[i2][j2]==val)
                        return false;
                }
            }
            return true;
        } 
        //回溯法求解数独
        public boolean shuDu(char[][] a, int i, int j){
            if(i==8&&j>=9){
                return true;
            }
            if(j==9){
                j=0;
                i++;
            }
            if(a[i][j]=='.'){
                char ch = '1';
                for(int k=0;k<9;k++){
                    if(isValid(a,i,j,(char)(ch+k))){
                        a[i][j] = (char) (ch+k);
                        //向下继续找
                        if(shuDu(a,i,j+1))
                            return true;
                        //如果没有找到全部答案将a[i][j]的值恢复
                        a[i][j] = '.';
                    }
                }
            }else{
                if(shuDu(a,i,j+1))
                    return true;
            }
            return false;
        }
        
        public void solveSudoku(char[][] board) {
            shuDu(board, 0, 0);
        }
    }

    算法调用示例如下:

    public class Main {

    public static void main(String[] args) {
    Solution solu = new Solution();
    char[][] sudoku = {
    {'8','.','.','.','.','.','.','.','.'},
    {'.','.','3','6','.','.','.','.','.'},
    {'.','7','.','.','9','.','2','.','.'},
    {'.','5','.','.','.','7','.','.','.'},
    {'.','.','.','.','4','5','7','.','.'},
    {'.','.','.','1','.','.','.','3','.'},
    {'.','.','1','.','.','.','.','6','8'},
    {'.','.','8','5','.','.','.','1','.'},
    {'.','9','.','.','.','.','4','.','.'}};
    long start = System.nanoTime();
    solu.solveSudoku(sudoku);
    long time = System.nanoTime() - start;
    System.out.println(time);
    for(int i=0;i<9;i++){
    for(int j=0;j<9;j++){
    System.out.print(sudoku[i][j]+" ");
    }
    System.out.println();
    }
    }
    }
  • 相关阅读:
    nginx 过滤了自定义的请求头参数
    Mysql5.7查看已经执行的sql语句
    Reids5 持久化
    JS 格式化时间,转成 几天前,几个月前
    个人小镜像站点
    记录一次清理Redis 病毒程序 kdevtmpfsi
    laravels 热重启
    Redis 布隆器安装和简单实现
    Redis Zset类型跳跃表算法实现(JAVA)
    Redis5 基于Lua实现分布式排它锁
  • 原文地址:https://www.cnblogs.com/gaopeng527/p/4873447.html
Copyright © 2020-2023  润新知