public static int[][] solve(int[][] input){
for (int i = 0; i < 9*9; i++){
if(input[i/9][i % 9] != 0){
continue;
}
for (int j = 1; j <= 9; j++){
if(validNumber(input, i/9, i % 9, j)){
input[i/9][i % 9] = j;
solve(input);
}
}
}
return input;
}
该方法应通过回溯解决(可解决的)数独难题,无论初始情况如何。它的工作原理是这样的:通过回溯解决数独(java)
给定一个数独谜题,它将从每一行的左上角迭代到二维数组的右下角。当已经有一个号码时,它会被跳过。当存在零(空场)时,它通过validNumber
方法计算可能的值。第一个有效数字(从1到9)放在该字段中,方法进入下一个字段。
在这个算法中,该方法现在不会生成一个有效的数字是否最终会使难题无法解决。
我想改变它像这样:
在结束时,当该方法结束通过整个2D阵列迭代,如果是零或不阵列的每个条目被测试。
如果甚至有一个零,则整个算法必须到达第一个“有效”号码所在的位置。现在,下一个“有效”号码被放入,直到没有零点算法的结尾。
我有一些麻烦实施这个想法。在我看来,在某个地方必须有另一个for循环,或者类似goto
声明,但我不知道该把它放在哪里。
有什么建议吗?
该策略需要一套全面的规则来消除数字。一些“硬”水平的数独谜题需要复杂的规则,基本上模仿尝试和检查的方法,而不用实际尝试不同的组合。我很好奇,如果你的求职者可以处理空谜作为输入。看到我的答案基于树的递归。我甚至用它来解决空白拼图问题,它在合理的有限时间(秒)内为我提供了正确的解决方案。 – Andrey
@Andrey - 不,我的解决方案无法处理空板。它基于“消除过程”。由于没有任何可以消除的东西,所以它会停下来。我的解决方案使用了6或7种不同的淘汰技术。唯一的尝试和检查方法是,当董事会留下只有3个空旷的广场,并没有其他消除技术可以解决它。源代码不是立即可用的(磁盘处于脱机状态),否则我会发布它。 – selbie
@selbie你是如何处理回溯?使用递归时,堆栈将跟踪移动历史,因此您通过返回到前一个堆栈框架来回溯。像你提到的迭代解决方案更适合称为“暴力”,而不是OP所尝试的。回溯不是蛮力。他只是没有做好回溯部分。我很想知道你的代码如何在现代台式机CPU上处理一个“硬”电路板(如我的代码答案中的文章)。我的代码在我的机器上需要大约75ms。没有回溯,我认为这是不可能解决的。 – The111