回溯法实现求解子集合和问题
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; } }
相关文章推荐
- 回溯法求解N皇后问题(Java实现)
- 贪心法和回溯法 求解“背包、0/1背包问题”——Java 实现
- javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题
- PHP实现基于回溯法求解迷宫问题的方法详解
- 01背包问题(用c语言实现)-回溯法求解
- 回溯法求解 “n 皇后 问题”——Java 实现
- 回溯法求解N人分N本书的问题(Java实现)
- 八皇后问题求解----C++实现
- 回溯法求解m着色问题
- 迷宫求解问题的简易实现(C++)
- 通过8皇后问题浅析回溯法的递归实现
- 用回溯法(backtracking)解决平衡集合问题(一道微软公司面试题)
- 经典算法(1)——8皇后问题求解(回溯法)
- 用Java实现天平称球问题的自动求解
- 贪心算法求解硬币问题的递归与非递归实现
- 动态规划算法求解找硬币问题的递归与非递归实现
- 0/1背包问题的动态规划法求解 —— Java 实现
- 用C语言实现迷宫求解问题
- 数组编码和解码问题的求解设计与实现
- 用回溯法求解跳马问题