有效的数独(Java)

该博客介绍了一个用于判断9x9数独是否有效的算法。算法通过检查每一行、每一列以及每个3x3宫格内的数字是否符合1-9不重复的规则,实现了数独的有效性验证。示例中给出了两个数独实例,一个有效,一个无效,用于说明算法的正确性。代码使用Java编写,通过HashSet存储每个行、列和宫格的数字,确保唯一性。
摘要由CSDN通过智能技术生成

判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
    1、数字 1-9 在每一行只能出现一次。
    2、数字 1-9 在每一列只能出现一次。
    3、数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

数独部分空格内已填入了数字,空白格用 0 表示。
示例1:
            { 5 , 3 , 0 , 0 , 7 , 0 ,0 , 0 , 0 },
            { 6 , 0 , 0 , 1 , 9 , 5 ,0 , 0 , 0 },
            { 0 , 9 , 8 , 0 , 0 , 0 ,0 , 6 , 0 },
            { 8 , 0 , 0 , 0 , 6 , 0 ,0 , 0 , 3 },
            { 4 , 0 , 0 , 8 , 0 , 3 ,0 , 0 , 1 },
            { 7 , 0 , 0 , 0 , 2 , 0 ,0 , 0 , 6 },
            { 0 , 6 , 0 , 0 , 0 , 0 ,2 , 8 , 0 },
            { 0 , 0 , 0 , 4 , 1 , 9 ,0 , 0 , 5 },
            { 0 , 0 , 0 , 0 , 8 , 0 ,0 , 7 , 9 }
输出:true

示例2:
            { 8 , 3 , 0 , 0 , 7 , 0 ,0 , 0 , 0 },
            { 6 , 0 , 0 , 1 , 9 , 5 ,0 , 0 , 0 },
            { 0 , 9 , 8 , 0 , 0 , 0 ,0 , 6 , 0 },
            { 8 , 0 , 0 , 0 , 6 , 0 ,0 , 0 , 3 },
            { 4 , 0 , 0 , 8 , 0 , 3 ,0 , 0 , 1 },
            { 7 , 0 , 0 , 0 , 2 , 0 ,0 , 0 , 6 },
            { 0 , 6 , 0 , 0 , 0 , 0 ,2 , 8 , 0 },
            { 0 , 0 , 0 , 4 , 1 , 9 ,0 , 0 , 5 },
            { 0 , 0 , 0 , 0 , 8 , 0 ,0 , 7 , 9 }
输出:false
但由于位于第一列宫内有两个 8 存在, 因此这个数独是无效的。

 

思路:
9 * 9 划分成 3 * 3个方格 = 9行划分成3份行格,9列也划分成3份列格。

    9行划分成3份行格
    i / 3 ,确定是第几份行格。
    如,第8行,8/3 = 2,第8行属于第2份行格(起始行为第0行)

    9列也划分成3份列格
    j / 3, 确定是第几份列格。
    如,第5行,5/3 = 1,第8行属于第1份行格(起始行为第0行)

    方格索引
    9 * 9 划分成 3 * 3个方格,行格下标为i / 3,列格下标为j / 3,也就是[x,y]=[i/3 , j/3]
    那么处于第几个方格就可以算出来了:x * 列格数 + y = i / 3 * 3 + j / 3

 

package com.loo;

import java.util.HashSet;

public class ValidSudo {

    public static final int sudoLength = 9;
    public static void main(String[] args) {
        int[][] arr = new int[][] {
            { 5 , 3 , 0 , 0 , 7 , 0 ,0 , 0 , 0 },
            { 6 , 0 , 0 , 1 , 9 , 5 ,0 , 0 , 0 },
            { 0 , 9 , 8 , 0 , 0 , 0 ,0 , 6 , 0 },
            { 8 , 0 , 0 , 0 , 6 , 0 ,0 , 0 , 3 },
            { 4 , 0 , 0 , 8 , 0 , 3 ,0 , 0 , 1 },
            { 7 , 0 , 0 , 0 , 2 , 0 ,0 , 0 , 6 },
            { 0 , 6 , 0 , 0 , 0 , 0 ,2 , 8 , 0 },
            { 0 , 0 , 0 , 4 , 1 , 9 ,0 , 0 , 5 },
            { 0 , 0 , 0 , 0 , 8 , 0 ,0 , 7 , 9 }
        };
        int[][] arr2 = new int[][] {
            { 8 , 3 , 0 , 0 , 7 , 0 ,0 , 0 , 0 },
            { 6 , 0 , 0 , 1 , 9 , 5 ,0 , 0 , 0 },
            { 0 , 9 , 8 , 0 , 0 , 0 ,0 , 6 , 0 },
            { 8 , 0 , 0 , 0 , 6 , 0 ,0 , 0 , 3 },
            { 4 , 0 , 0 , 8 , 0 , 3 ,0 , 0 , 1 },
            { 7 , 0 , 0 , 0 , 2 , 0 ,0 , 0 , 6 },
            { 0 , 6 , 0 , 0 , 0 , 0 ,2 , 8 , 0 },
            { 0 , 0 , 0 , 4 , 1 , 9 ,0 , 0 , 5 },
            { 0 , 0 , 0 , 0 , 8 , 0 ,0 , 7 , 9 }
        };
        System.out.println(isValidSudo(arr));
        System.out.println(isValidSudo(arr2));
    }

    public static boolean isValidSudo(int[][] board) {
        if (board == null || board.length != sudoLength || board[0].length != sudoLength) {
            System.out.println("isValidSudo Error!!!");
            return false;
        }
        HashSet<Integer>[] rows = new HashSet[sudoLength];
        HashSet<Integer>[] cols = new HashSet[sudoLength];
        HashSet<Integer>[] boxes = new HashSet[sudoLength];
        for (int i=0;i<sudoLength;i++) {
            rows[i] = new HashSet<Integer>();
            cols[i] = new HashSet<Integer>();
            boxes[i] = new HashSet<Integer>();
        }
        for (int i=0;i<sudoLength;i++) {
            for (int j=0;j<sudoLength;j++) {
                int temp = board[i][j];
                if (temp == 0) {
                    continue;
                }
                if (rows[i].contains(temp) || cols[j].contains(temp) || boxes[(i/3)*3+j/3].contains(temp)) {
                    return false;
                }
                rows[i].add(temp);
                cols[j].add(temp);
                boxes[(i/3)*3+j/3].add(temp);
            }
        }
        return true;
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值