- 不规则数独问题。
33填数独,
每一行要填1~3,
每一列要填1~3,
33的区域会拆分成不规则的三个集团区域,
每个集团区域3个格子,
每个集团的区域都一定是一个连在一起的整体,可能不规则,
每个集团内要填1~3,
如果只有一个解返回"Unique",如果有多个解返回"Multiple",如果没有解返回"No"。
解析请看,大厂刷题班,28节,leetcode原题,数独那两个题。
本题就是改变一下桶的归属而已。
来自网易。
————————————————
版权声明:本文为CSDN博主「福大大架构师每日一题」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_48502062/article/details/125136177
/**
* 不规则数独问题
*
* @param sudoku
* @param map
* @return
*
*/
public String solution(int[][] sudoku,int[][][] map){
boolean[][] row = new boolean[3][4];
boolean[][] col = new boolean[3][4];
boolean[][] bucket = new boolean[3][4];
int[][] own = new int[3][3];
//分别将集团内的元素(1,2,3)值给放入到own二维数组中
for (int i=0;i<3;i++){
for (int[] arr:map[i]){
own[arr[0]][arr[1]] = i;
}
}
//进行初始化这个数组中的值
for (int i=0;i<3;i++){
for (int j=0;j<3;j++){
//这个位置的点有数字,不需要进行填写
if (sudoku[i][j] !=0){
row[i][sudoku[i][j]] = true;
col[j][sudoku[i][j]] = true;
//将这个点给放入到桶之中
bucket[own[i][j]][sudoku[i][j]] = true;
}
}
}
//进行递归得到结果
int ans = process(sudoku,0,0,row,col,bucket,own);
return ans ==0?"No":(ans==1?"Unique":"Multiple");
}
private int process(int[][] sudoku, int i, int j, boolean[][] row, boolean[][] col, boolean[][] bucket, int[][] own) {
if (i==3){
return 1;
}
//下一个点的坐标
int nexti = j!=2?i:i+1;
int nextj = j!=2?j+1:0;
//位置有数据,不需要填
if (sudoku[i][j] !=0){
//递归到下一个点上面
return process(sudoku,nexti,nextj,row,col,bucket,own);
}else {
int ans =0;
//属于哪个集团下面的值
int bid = own[i][j];
for (int num=1;num<=3;num++){
//这个点是没有被填写的
if ((!row[i][num]) && (!col[j][num]) &&(!bucket[bid][num])){
row[i][num] = true;
col[j][num] = true;
bucket[bid][num] = true;
sudoku[i][j] = num;
ans+=process(sudoku,nexti,nextj,row,col,bucket,own);
//回溯
row[i][num] = false;
col[j][num] = false;
bucket[bid][num] = false;
sudoku[i][j] = 0;
if (ans>1){
return ans;
}
}
}
return ans;
}
}