数独(LeetCode37. Sudoku Solver ) 回溯法-java

百科:数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。

如下所示:给定一个空缺的9宫格,完成数独,给出一种结果就好,想要多个结果的(用list集合装,把backTracking函数返回值改为void就好了)
在这里插入图片描述

结题思路:
回溯法
从头到尾遍历每个位置,每个位置如果没有数字(本例中对应为0),则在该位置m从1~9开始安放,例如安放1后,开始遍历下个位置n,若失败,则退回位置m,开始安放2,依次类推,典型的回溯思想

package BackTracking;

import java.util.Arrays;

/**回溯算法(难)
 * 填充数独
 * @author Archerlu
 *
 */
public class Sudoku {
	public static void main(String[] args) {
		int[][] arr = {{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}};
		boolean canSudoku = sudokuSovler(arr);
		System.out.println(canSudoku);
		for(int i=0;i<arr.length;i++) {
			System.out.println(Arrays.toString(arr[i]));
		}
	}

	private static boolean sudokuSovler(int[][] arr) {
		if(arr==null||arr.length!=9||arr[0].length!=9) return false;
		boolean[][] rowFlag = new boolean[9][10]; //指定行row有无数字num(0-9),有的话rowFlag[row][num]=true,
		boolean[][] colFlag = new boolean[9][10]; //指定列
		boolean[][] cubeFlag = new boolean[9][10];//指定3*3小立方体区域,我是按行读的
		for(int i=0;i<9;i++) {
			for(int j=0;j<9;j++) {
				int num = arr[i][j];
				rowFlag[i][num] = true;
				colFlag[j][num] = true;
				int cubeIndex = i/3*3+j/3;
				cubeFlag[cubeIndex][num] = true;
			}
		}
		
		return backTracking(arr,rowFlag,colFlag,cubeFlag,0,0);
	}

	private static boolean backTracking(int[][] arr, boolean[][] rowFlag, boolean[][] colFlag, boolean[][] cubeFlag, int m,
			int n) {
		while(m<9&&arr[m][n]!=0) {  //当坐标对应数组元素不为零时,更新坐标
			if(n==8) {
				m++;
				n=0;
			}else {
				n++;
			}
		}
		if(m==9) return true; //行m==9,说明前9行已经填充完毕,大功告成 返回true
		for(int i=1;i<=9;i++) {
			if(rowFlag[m][i]||colFlag[n][i]||cubeFlag[(m/3)*3+n/3][i]) continue;  //指定行或指定列或指定小立方区域已经有该值i了,弃用i
			rowFlag[m][i] = colFlag[n][i] = cubeFlag[m/3*3+n/3][i] = true;
			arr[m][n] = i;
			if(backTracking(arr,rowFlag,colFlag,cubeFlag,m,n)) {
				return true;
			}
			arr[m][n] = 0;
			rowFlag[m][i] = colFlag[n][i] = cubeFlag[m/3*3+n/3][i] = false;
		}
		
		return false;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值