判断一个 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; }
}