回溯法求解數獨問題的思路和程式碼
阿新 • • 發佈:2019-01-08
在刷題的時候遇到了一個求解數獨的問題,用回溯法寫了以下程式碼,記錄一下,之後探究有沒有更好的演算法。
演算法思路: ①讀取待求解陣列,其中待填位置為0。 ②將所有待填位置的兩個座標(行列)和目前數字封裝起來壓入棧1中。 ③開一個棧2用於儲存目前確定的答案。 ④當棧1不為空的時候,取棧頂元素,從元素當前值加一開始依次到9判斷是否可以填入,若可以則將當前元素壓入棧2,否則壓回棧1並且取出棧2棧頂元素押回棧1; ⑤重複④,直到棧1為空。
java程式碼如下: public class Main {
public static void main(String[] args) { Stack<Index> stack = new Stack<>(); Stack<Index> stack2 = new Stack<>(); Scanner in = new Scanner(System.in);
while (in.hasNext()) {
int[][] num = new int[9][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
int t = in.nextInt();
if (t == 0) {
stack.push(new Index(0, i, j));
}
num[i][j] = t;
} } while (!stack.isEmpty()) { Index top = stack.pop(); int i = top.num + 1; for (; i <= 9; i++) { num[top.row][top.col] = i; if (isRight(top.row, top.col, num)) { top.num = i; break; } } if (i == 10 && !stack2.isEmpty()) { //沒答案 num[top.row][top.col] = 0; top.num = 0; stack.push(top); stack.push(stack2.pop()); } else { stack2.push(top); }
} for (int i = 0; i < 9; i++) { for (int j = 0; j < 8; j++) { System.out.print(num[i][j] + " "); } System.out.print(num[i][8]); System.out.println(); } } }
private static boolean isRight(int row, int col, int[][] a) { for (int i = 0; i < 9; i++) { if (i == col || a[row][i] == 0) { continue; } if (a[row][i] == a[row][col]) { return false; } } for (int i = 0; i < 9; i++) { if (i == row || a[i][col] == 0) { continue; } if (a[i][col] == a[row][col]) { return false; } } return true; } }
class Index { public int num; public int row; public int col;
public Index(int num, int row, int col) { this.num = num; this.row = row; this.col = col; } }
執行示例:
演算法思路: ①讀取待求解陣列,其中待填位置為0。 ②將所有待填位置的兩個座標(行列)和目前數字封裝起來壓入棧1中。 ③開一個棧2用於儲存目前確定的答案。 ④當棧1不為空的時候,取棧頂元素,從元素當前值加一開始依次到9判斷是否可以填入,若可以則將當前元素壓入棧2,否則壓回棧1並且取出棧2棧頂元素押回棧1; ⑤重複④,直到棧1為空。
java程式碼如下: public class Main {
public static void main(String[] args) { Stack<Index> stack = new Stack<>(); Stack<Index> stack2 = new Stack<>(); Scanner in = new Scanner(System.in);
} } while (!stack.isEmpty()) { Index top = stack.pop(); int i = top.num + 1; for (; i <= 9; i++) { num[top.row][top.col] = i; if (isRight(top.row, top.col, num)) { top.num = i; break; } } if (i == 10 && !stack2.isEmpty()) { //沒答案 num[top.row][top.col] = 0; top.num = 0; stack.push(top); stack.push(stack2.pop()); } else { stack2.push(top); }
} for (int i = 0; i < 9; i++) { for (int j = 0; j < 8; j++) { System.out.print(num[i][j] + " "); } System.out.print(num[i][8]); System.out.println(); } } }
private static boolean isRight(int row, int col, int[][] a) { for (int i = 0; i < 9; i++) { if (i == col || a[row][i] == 0) { continue; } if (a[row][i] == a[row][col]) { return false; } } for (int i = 0; i < 9; i++) { if (i == row || a[i][col] == 0) { continue; } if (a[i][col] == a[row][col]) { return false; } } return true; } }
class Index { public int num; public int row; public int col;
public Index(int num, int row, int col) { this.num = num; this.row = row; this.col = col; } }
執行示例: