算法:求解Sukodu数独

2021-04-01 03:28

阅读:723

问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足每一行、每一列、每一个粗线宫内的数字均含1-9,并且不重复。
输入:
包含已知数字的9X9盘面数组[空缺位以数字0表示]
输出:
完整的9X9盘面数组

思路

这题在leetcode上见过,当时没有去解。直观上感受题目,最先想到的还是暴力遍历每种情况,但害怕时间复杂度会特别的高,所以迟迟不敢下手,今天实在是想不到了,就看了下别人的想法,发现还是深度遍历各种情况,草。

代码

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {
    private static int[][] m;
    public static void main(String...a){
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            m = new int[9][9];
            for (int i = 0; i 9; i++) {
                for (int j = 0; j 9; j++) {
                    m[i][j] = in.nextInt();
                }
            }

            helper(0, 0);

            for (int i = 0; i 9; i++) {
                for (int j = 0; j 9; j++) {
                    System.out.print(m[i][j]);
                    if (j 8) System.out.print( );
                }
                System.out.println();
            }
        }
    }
    private static Boolean helper(int x, int y){
    /*
        从二维数组的m[0][0]开始扫描第一行,当扫描到行尾时,转入扫描下一行。
        扫描过的位置代表里边的数字符合规则,若能扫描到完最后一行,那么说明整个数独填补完了
        当扫描到一个空位时,开始尝试填入数字,当所数字1-9都不能填补这个位置时,说明前面某个填的位置出现错误
    */
        if (x >= 9) return true;
        if (y >= 9) return helper(x+1, 0);
        if (m[x][y] != 0) return helper(x, y + 1);

        Set existsNum = getExistsNum(x, y);
        for (int i = 1; i 9; i++) {
            if (existsNum.contains(i)) continue;
            m[x][y] = i;
            if (helper(x, y + 1)) {
                return true;
            }
            m[x][y] = 0;
        }
        return false;
    }
    private static Set getExistsNum(int x, int y){
        Setset = new HashSet();
        for (int i = 0; i 9; i++) {//查看行和列出现过的数字
            if (m[x][i] != 0) {
                set.add(m[x][i]);
            }
            if (m[i][y] != 0) {
                set.add(m[i][y]);
            }
        }
        int startX = x / 3 * 3, startY = y / 3 * 3;
        for (int i = 0; i 3; i++) {//查看九宫格中出现过的数字
            for (int j = 0; j 3; j++) {
                if (m[startX + i][startY + j] != 0) {
                    set.add(m[startX + i][startY + j]);
                }
            }
        }
        return set;
    }
}
       

 


评论


亲,登录后才可以留言!