两个经典递归模板,以前写过,现在再过一遍!
基本思路:
如果题目给的输入时数组,首先先要把数组转为ArrayList,因为ArrayList可以很方便地插入,删除,添加!
其次,递归函数的形式都一样,一共有3个参数,分别叫ArrayList<Integer> done, ArrayList<Integer> rest, ArrayList<ArrayList<Integer>> ret 。 done存放已经处理过的数据,rest存放还没处理的数据,ret存放最后的结果。注意这里的Integer可以是泛型,任意的data type。
具体思路:
全排列:对A[0,1,2,3...n] 每次依次取一个元素,添加到done里,然后对剩下的rest递归,直到rest为空。所以总的结构就是一个for循环里面,有一个从rest取数据,递归,撤销的过程。所以总结一下就是,每次递归,轮流从rest里取数据,依次添加到done。
子集:每次取出rest的第一个元素,然后做决定是否添加到done里面,可以添加,也可以不添加,所以会有两个递归。所以总结一下就是,每次递归,总是取rest的第一个数据,然后做两种选择。
import java.util.*; public class HelloWorld{ public static void main(String []args){ int[] A = {1,2,3}; subset(A); permutation(A); String s = "abc"; permutationStringRec(new StringBuilder(), new StringBuilder(s)); } // ======================================================= permutation public static void permutation(int[] A) { ArrayList<Integer> rest = new ArrayList<Integer>(); ArrayList<Integer> done = new ArrayList<Integer>(); ArrayList<ArrayList<Integer>> ret = new ArrayList<ArrayList<Integer>>(); for(int i : A) { rest.add(i); } permutationRec(done, rest, ret); System.out.println(ret); } public static void permutationRec(ArrayList<Integer> done, ArrayList<Integer> rest, ArrayList<ArrayList<Integer>> ret) { if(rest.size() == 0) { ret.add(new ArrayList<Integer>(done)); return; } for(int i=0; i<rest.size(); i++) { int val = rest.get(i); // 选择第i个元素,添加到done done.add(val); rest.remove(i); permutationRec(done, rest, ret); rest.add(i, val); done.remove(done.size()-1); } } // ======================================================= subset public static void subset(int[] A) { ArrayList<Integer> rest = new ArrayList<Integer>(); ArrayList<Integer> done = new ArrayList<Integer>(); ArrayList<ArrayList<Integer>> ret = new ArrayList<ArrayList<Integer>>(); for(int i : A) { rest.add(i); } subsetRec(done, rest, ret); System.out.println(ret); } public static void subsetRec(ArrayList<Integer> done, ArrayList<Integer> rest, ArrayList<ArrayList<Integer>> ret) { if(rest.size() == 0) { ret.add(new ArrayList<Integer>(done)); return; } int first = rest.remove(0); // 选择添加到done done.add(first); subsetRec(done, rest, ret); done.remove(done.size()-1); // 选择不添加到done subsetRec(done, rest, ret); rest.add(0, first); } // ======================================== permutationStringRec 另一种用StringBuilder的变型版 public static void permutationStringRec(StringBuilder done, StringBuilder rest){ if(rest.length() == 0) { System.out.println(done.toString()); return; } for(int i=0; i<rest.length(); i++) { char c = rest.charAt(i); done.append(c); rest.deleteCharAt(i); permutationStringRec(done, rest); rest.insert(i, c); done.deleteCharAt(done.length()-1); } } }
总结帖:全排列Permutation,子集subset 递归模板,布布扣,bubuko.com
总结帖:全排列Permutation,子集subset 递归模板
原文:http://blog.csdn.net/fightforyourdream/article/details/20598735