LeetCode回溯法解數獨

 數獨一般只有一個解,這裏給出一個多解的數獨測試程序。總共13個解。如其中一個解爲:

|7 8 1 |6 4 5 |3 2 9 
|9 2 5 |1 7 3 |4 6 8 
|3 6 4 |9 2 8 |7 5 1 

|8 7 9 |5 6 4 |2 1 3 
|5 3 2 |7 8 1 |6 9 4 
|1 4 6 |2 3 9 |8 7 5 

|4 1 7 |8 9 2 |5 3 6 
|2 9 3 |4 5 6 |1 8 7 
|6 5 8 |3 1 7 |9 4 2 

如果是標準數獨,只有一個解,那麼最好設置一個boolean變量,表示是否得到解,之後所有的回溯函數都直接return,減少時間

public class Sth {
	int count = 0;
	int[][] a;
	int[][] rows;
	int[][] cols;
	int[][] boxes;

	public void solve(String[] str) {
		strToInt(str);
		backTrack(0, 0);
		System.out.println("解法有:" + count);
	}

	public boolean couldPlace(int i, int row, int col) {
		int box = (row / 3) * 3 + col / 3;
		return rows[row][i] + cols[col][i] + boxes[box][i] == 0;
	}

	public void backTrack(int row, int col) {
		if (a[row][col] == 0) {
			for (int i = 1; i <= 9; i++) {
				if (couldPlace(i, row, col)) {
					place(i, row, col);
					if (row == 8 && col == 8) {
						count++;
						print(a);
					} else if (col == 8)
						backTrack(row + 1, 0);
					else
						backTrack(row, col + 1);
					remove(i, row, col);
				}
			}
		} else if (row == 8 && col == 8) {
			count++;
			print(a);
		} else if (col == 8)
			backTrack(row + 1, 0);
		else
			backTrack(row, col + 1);
	}

	private void print(int[][] a) {
		for (int i = 0; i < 9; i++) {
			if (i % 3 == 0)
				System.out.println("");
			for (int j = 0; j < 9; j++) {
				if (j % 3 == 0)
					System.out.print("|");
				System.out.print(a[i][j] + " ");
			}
			System.out.println();
		}
		System.out.println("--------------------");
	}

	private void remove(int i, int row, int col) {
		a[row][col] = 0;
		rows[row][i] = 0;
		cols[col][i] = 0;
		boxes[(row / 3) * 3 + col / 3][i] = 0;
	}

	private void place(int i, int row, int col) {
		a[row][col] = i;
		rows[row][i] = 1;
		cols[col][i] = 1;
		boxes[(row / 3) * 3 + col / 3][i] = 1;
	}

	public void strToInt(String[] str) {
		int m = str.length, n = str[0].length();
		a = new int[m][n];
		rows = new int[m][n + 1];
		cols = new int[m][n + 1];
		boxes = new int[m][n + 1];
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				int tmp = str[i].charAt(j) - 48;
				if (tmp != 0) {
					a[i][j] = tmp;
					rows[i][tmp] = 1;
					cols[j][tmp] = 1;
					boxes[(i / 3) * 3 + j / 3][tmp] = 1;
				}

			}
		}
	}

	public static void main(String[] args) {
		Sth sth = new Sth();
		String[] str = { 
				"000000009", "020100400", "004020700", 
				"800004210", "000701000", "046200005", 
				"007090500", "003006080", "600000000" 
				};
		sth.solve(str);
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章