7.15 - Java第二章2.11
一、回溯思想
回溯算法是为了解决按照特定路线穷举的问题。比如说自动寻路、走迷宫、数独等需要列举所有结果并选择能够完成任务的路线的问题。
二、回溯算法解题框架
public void backTrace(int i){
if(i > x)
return; // 终止条件
// 做选择
doSelect();
// 进入下一层
backTrace(i + 1);
// 撤销选择
cancelSelect();
}
三、解决问题
3.1 简单数独问题
假定给定只有一排的棋盘,里面有几个位置已经被填了数字,列举数独的所有情况。
思路:
- 将已有的数字标记起来(标记法)
- 尝试将1-9数字放入空格中(首先要判断该位置是否能填,如果不能填有两种情况:1. 当前空格已有数字。 2. 当前要填的数字已经被标记过即已经在棋盘中存在)
- 当最后一个格子填满的时候终止。
代码:
public class EasySudoku {
public static void play(int[] chessboard) {
// 1.将已有的数字标记起来,对应一个数组的索引,标记为1
int[] exists = new int[9];
for (int cell : chessboard) {
if (cell != 0)
exists[cell - 1] = 1;
}
// 2.进入游戏
helper(chessboard, exists, 0);
}
private static void helper(int[] chessboard, int[] exists, int curCol) {
// curCol即当前列到最后一列的时候打印数组并终止。
if (curCol == chessboard.length) {
printArray(chessboard);
return;
}
for (int num = 1; num < 10; num++) {
// 说明当前空格没有棋子,满足第一种判断
if (chessboard[curCol] == 0) {
// 说明当前空格没有棋子,且将要填的棋子没有被标记