版本一
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Suduku3 {
public static final Set<Integer> nums = Stream.iterate(1, n -> n + 1).limit(9).collect(Collectors.toSet());
public static int round = 0;
public static int[][] solve(int[][] sudo) {
round++;
if (check(sudo)) {
return sudo;
}
Map<String, Object> map = find(sudo);
Set<Integer> backs = (Set<Integer>) map.get("result");
if (backs != null && backs.size() > 0) {
for (Integer back : backs) {
int[][] cpsudo = copy(sudo);
int i = (int) map.get("i");
int j = (int) map.get("j");
cpsudo[i][j] = back;
cpsudo = solve(cpsudo);
if (check(cpsudo)) {
return cpsudo;
}
}
}
return sudo;
}
private static Map<String, Object> find(int[][] sudo) {
Map<String, Object> map = new HashMap<>();
Set<Integer> result = new HashSet<>(nums);
for (int i = 0; i < sudo.length; i++) {
for (int j = 0; j < sudo[i].length; j++) {
if (sudo[i][j] == 0) {
Set<Integer> backs = new HashSet<>(nums);
for (int m = 0; m < sudo.length; m++) {
for (int n = 0; n < sudo[m].length; n++) {
if (sudo[m][n] > 0) {
if (m == i || n == j) {
backs.remove(sudo[m][n]);
}
if (m / 3 == i / 3 && n / 3 == j / 3) {
backs.remove(sudo[m][n]);
}
}
}
}
if (backs.size() < result.size()) {
result = new HashSet<>(backs);
map.put("i", i);
map.put("j", j);
map.put("result", result);
}
}
}
}
return map;
}
public static void print(int[][] sudo) {
for (int[] ints : sudo) {
for (int anInt : ints) {
System.out.print(anInt + " ");
}
System.out.println();
}
System.out.println("===============================================");
}
public static boolean check(int[][] sudo) {
if (null == sudo) {
return false;
}
for (int i = 0; i < sudo.length; i++) {
for (int j = 0; j < sudo[i].length; j++) {
if (sudo[i][j] == 0) {
return false;
}
int num = sudo[i][j];
for (int m = 0; m < sudo.length; m++) {
for (int n = 0; n < sudo[m].length; n++) {
if (m == i && n == j) {
continue;
}
if (sudo[m][n] == num) {
if (m == i || n == j) {
return false;
}
if (m / 3 == i / 3 && n / 3 == j / 3) {
return false;
}
}
}
}
}
}
return true;
}
public static int[][] copy(int[][] arrays) {
int[][] result = new int[arrays.length][arrays[0].length];
for (int i = 0; i < arrays.length; i++) {
for (int j = 0; j < arrays[i].length; j++) {
result[i][j] = arrays[i][j];
}
}
return result;
}
public static void main(String[] args) {
int[][] sudo = new int[][]{
{0, 0, 0, 0, 0, 3, 0, 0, 5},
{8, 0, 0, 0, 0, 0, 0, 9, 0},
{0, 5, 0, 2, 0, 0, 8, 0, 6},
{0, 0, 0, 8, 2, 0, 0, 5, 9},
{0, 0, 4, 0, 0, 0, 6, 0, 0},
{2, 9, 0, 0, 3, 1, 0, 0, 0},
{9, 0, 2, 0, 0, 8, 0, 4, 0},
{0, 4, 0, 0, 0, 0, 0, 0, 7},
{3, 0, 0, 1, 0, 0, 0, 0, 0}
};
Date start = new Date();
sudo = solve(sudo);
print(sudo);
System.out.println(round);
System.out.println(new Date().getTime() - start.getTime());
}
}
版本二(减少递归调用)
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Suduku2 {
public static int round = 0;
public static final Set<Integer> nums = Stream.iterate(1, n -> n + 1).limit(9).collect(Collectors.toSet());
public static int[][] solve(int[][] sudo) {
round++;
if (check(sudo)) {
return sudo;
}
int[][] cpsudo = copy(sudo);
List<Map<String, Integer>> mapList = findOnlyOne(sudo);
for (Map<String, Integer> objectMap : mapList) {
int i = objectMap.get("i");
int j = objectMap.get("j");
int n = objectMap.get("result");
cpsudo[i][j] = n;
if (check(cpsudo)) {
return cpsudo;
}
}
Map<String, Object> map = find(sudo);
Set<Integer> backs = (Set<Integer>) map.get("result");
if (backs != null && backs.size() > 0) {
for (Integer back : backs) {
int[][] cp2 = copy(cpsudo);
int i = (int) map.get("i");
int j = (int) map.get("j");
cp2[i][j] = back;
cp2 = solve(cp2);
if (check(cp2)) {
return cp2;
}
}
}
return cpsudo;
}
private static List<Map<String, Integer>> findOnlyOne(int[][] sudo) {
List<Map<String, Integer>> list = new ArrayList<>();
for (int i = 0; i < sudo.length; i++) {
for (int j = 0; j < sudo[i].length; j++) {
if (sudo[i][j] != 0) {
continue;
}
Set<Integer> backs = new HashSet<>(nums);
for (int m = 0; m < sudo.length; m++) {
for (int n = 0; n < sudo[m].length; n++) {
if (sudo[m][n] == 0) {
continue;
}
if (m == i || n == j
|| (m / 3 == i / 3 && n / 3 == j / 3)) {
backs.remove(sudo[m][n]);
}
}
}
if (backs.size() == 1) {
Map<String, Integer> map = new HashMap<>();
map.put("i", i);
map.put("j", j);
map.put("result", backs.iterator().next());
sudo[i][j] = map.get("result");
list.add(map);
}
}
}
if (list.size() > 0) {
list.addAll(findOnlyOne(sudo));
return list;
} else {
return list;
}
}
private static Map<String, Object> find(int[][] sudo) {
Map<String, Object> map = new HashMap<>();
Set<Integer> result = new HashSet<>(nums);
for (int i = 0; i < sudo.length; i++) {
for (int j = 0; j < sudo[i].length; j++) {
if (sudo[i][j] != 0) {
continue;
}
Set<Integer> backs = new HashSet<>(nums);
for (int m = 0; m < sudo.length; m++) {
for (int n = 0; n < sudo[m].length; n++) {
if (sudo[m][n] == 0) {
continue;
}
if (m == i || n == j
|| (m / 3 == i / 3 && n / 3 == j / 3)) {
backs.remove(sudo[m][n]);
}
}
}
if (backs.size() < result.size()) {
result = new HashSet<>(backs);
map.put("i", i);
map.put("j", j);
map.put("result", result);
}
}
}
return map;
}
public static void print(int[][] sudo) {
for (int[] ints : sudo) {
for (int anInt : ints) {
System.out.print(anInt + " ");
}
System.out.println();
}
System.out.println("===============================================");
}
public static boolean check(int[][] sudo) {
if (null == sudo) {
return false;
}
for (int i = 0; i < sudo.length; i++) {
for (int j = 0; j < sudo[i].length; j++) {
if (sudo[i][j] == 0) {
return false;
}
int num = sudo[i][j];
for (int m = 0; m < sudo.length; m++) {
for (int n = 0; n < sudo[m].length; n++) {
if ((m == i && n == j) || sudo[m][n] != num) {
continue;
}
if (m == i || n == j
|| (m / 3 == i / 3 && n / 3 == j / 3)) {
return false;
}
}
}
}
}
return true;
}
public static int[][] copy(int[][] arrays) {
int[][] result = new int[arrays.length][arrays[0].length];
for (int i = 0; i < arrays.length; i++) {
for (int j = 0; j < arrays[i].length; j++) {
result[i][j] = arrays[i][j];
}
}
return result;
}
public static void main(String[] args) {
int[][] sudo = new int[][]{
{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}
};
Date start = new Date();
print(solve(sudo));
System.out.println(round);
Date parse1 = new Date();
System.out.println(parse1.getTime() - start.getTime());
}
}