您的位置:首页 > 其它

回溯法实现求解子集合和问题

2017-05-15 15:34 411 查看

1.回溯法简介

  回溯法是一种在解空间搜索问题的解的方法。它在问题的解空间树种,按深度优先的策略,从根节点出发搜索解空间树。算法搜索至解空间树的任一节点时,先判断该节点是否包含问题的解。如果不包含,则跳过对以该节点为根的子树的搜索,逐层向其祖先节点回溯,否则进入该子树,继续按深度优先策略搜索。用回溯法求解问题的所有解的时,要回溯到根,且根节点的所有子树都被搜索遍才结束。用回溯法求问题的一个解时,只要搜索到问题的一个解就可以结束了,这种以深度优先方式系统搜索问题解的算法称为回溯法。

2.子集合和问题

  


3.代码

package depth.first.search;

import java.util.Scanner;
import java.util.Stack;
/***
* 用深度优先算法求一个数组的子数组的和是否能达到某个值
* 回溯法
* @author admin
*
*/
public class Subarray {

public static void main(String[] args) {
int n;
Scanner in = new Scanner(System.in);
n = in.nextInt();
int[] array = new int
;
for (int i = 0; i < array.length; i++) {
array[i] = in.nextInt();
}
//深度优先使用的数据结构
Stack<Integer> s = new Stack<Integer>();
//记录当前回溯的位置
Stack<Integer> s1 = new Stack<Integer>();
int sum = 0;
int k = 0,j = 0;
boolean judge = false;
while(k<n){
//约束条件
if(array[k]>9){
k++;
continue;
}
s.push(array[k]);
s1.push(k);
sum = array[k];
j = k+1;
if(sum==9){
judge  = true;
break;
}
while(!s.isEmpty() && j<n){
if(array[j]>9){
j++;
if(j==n){
sum = sum - s.pop();//弹出时应该减去那个值
j = s1.pop()+1;
}
continue;
}
sum = sum + array[j];
if(sum==9){//找到结束
s.push(array[j]);
s1.push(j);
judge = true;
break;
}else if(sum > 9){//太大,不压入栈
sum = sum - array[j];
}else{
s.push(array[j]);
s1.push(j);
}
j++;
if(j==n){
sum = sum - s.pop();//弹出时应该减去那个值
j = s1.pop()+1;
}
}
if(judge){
break;
}
k++;
}

if(judge){
for (Integer integer : s) {
System.out.p
9ad5
rint(integer+" ");
}
}else{
System.out.println("找不到这样的子数组");
}
}

}


非递归实现:
package depth.first.search;

import java.util.Scanner;
import java.util.prefs.BackingStoreException;

public class RecursiveSubArray {

private int add = 0;
//子数组的和
private int sum = 0;
private boolean judge = false;
public static void main(String[] args) {
int n;
Scanner in = new Scanner(System.in);
n = in.nextInt();
//对应的集合
int[] array = new int
;
for (int i = 0; i < array.length; i++) {
array[i] = in.nextInt();
}
//用来记录哪个元素被选用
int[] record = new int
;
RecursiveSubArray r =  new RecursiveSubArray();
//子集合和为9
r.sum = 9;
r.backtrack(0, array, record);
if(r.judge){
for (int i = 0; i < n; i++) {
if(record[i]==1){
System.out.print(array[i]+" ");
}
}
}
}

//回溯法
public boolean backtrack(int t,int[] array,int[] record){
if(t<array.length){
add = add + array[t];
if(add==sum){
record[t] = 1;
judge = true;
return judge;
}else if(add > sum){
add = add - array[t];
if(backtrack(t+1, array, record)){
return true;
}

}else{
record[t] = 1;//选择该元素
if(backtrack(t+1, array, record)){
return true;
}else{
record[t] = 0;//不选该元素
add = add - array[t];
if(backtrack(t+1, array, record)){
return true;
}
}
}
}
return false;

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: