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

来源:互联网 发布:淘宝如何推广自己的店铺 编辑:程序博客网 时间:2024/05/16 06:10

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[n];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.print(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[n];for (int i = 0; i < array.length; i++) {array[i] = in.nextInt();}//用来记录哪个元素被选用int[] record = new int[n];RecursiveSubArray r =  new RecursiveSubArray();//子集合和为9r.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;}}


0 0