回溯法求解
: 求一组解 , 全部解 或 最优解.
实质:
先序遍历一颗
非预先建立的 状态树, 数
隐含在遍历过程中。
情况1: 求解的树为满二叉树, 每一个叶子节点都是一个解。
例:求幂集:集合A的幂集是由集合A的所有自集组成的集合。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
public
class
TreeCase1 {
public
static
void
main(String[] args){
ArrayList<Integer> set =
new
ArrayList<>();
//集合
set.add(
1
); set.add(
2
); set.add(
3
);
int
i =
0
;
ArrayList<Integer> misets =
new
ArrayList<>();
//集合
getMiSet(i,set,misets);
//求幂集
//结果
// 1 2 3
// 1 2
// 1 3
// 1
// 2 3
// 2
// 3
// 空
}
//求幂集
private
static
void
getMiSet(
int
i, ArrayList<Integer> set, ArrayList<Integer> misets) {
if
(i >= set.size()) {
for
(Integer integer : misets) {
System.out.print(integer +
" "
);
}
System.out.println();
}
else
{
int
ele = set.get(i);
int
k = misets.size();
//左分支取元素ele加入集合
misets.add(ele); getMiSet(i+
1
,set,misets);
//右分支不取元素ele到集合
misets.remove(k); getMiSet(i+
1
,set,misets);
}
}
}
|
情况2 :求解的数为非满二叉树,即在
约束条件 下进行遍历, 并在遍历过程中
剪去不满足的分支。
例如:八皇后问题,相当于先序遍历一颗树
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
// 八皇后问题
//一种答案:
/*row:0col:0
row:1col:4
row:2col:7
row:3col:5
row:4col:2
row:5col:6
row:6col:1
row:7col:3*/
public
class
EightQueen {
public
static
final
int
SIZE =
8
;
private
int
[] queens =
new
int
[SIZE];
public
EightQueen(){
search(
0
);
}
private
void
search(
int
row) {
if
(row == SIZE){
for
(
int
i=
0
;i<SIZE;i++)
System.out.println(
"row:"
+i+
"col:"
+queens[i]);
System.out.println(
"============================"
);
}
else
{
for
(
int
i=
0
;i<SIZE;i++){
//row行i列
queens[row] = i;
if
(isValid(row,i)) search(row+
1
);
//约束条件
}
}
}
private
boolean
isValid(
int
row,
int
column) {
for
(
int
i=
1
;i<=row;i++)
if
(queens[row-i] == column || queens[row-i] == column-i || queens[row-i] == column+i)
return
false
;
return
true
;
}
public
static
void
main(String[] args){
EightQueen eightQueen =
new
EightQueen();
}
}
|