字符串的全排列和全组合
输入:abc
输出:bac,cba,acb,bca,cab,abc
全排列的问题:
基本思想就是递归,固定第一个数,先求后面的所有的数的全排列,再用这个固定的数和后面的每个数来交换,注意重复字符的处理。
public ArrayList<String> Permutation(String str) { ArrayList<String> list = new ArrayList<String>(); if(str!=null && str.length()>0){ helper(str.toCharArray(),list,0); Collections.sort(list); } return list; } public void helper(char[] chars,ArrayList<String> list,int i) { if(i==chars.length-1) { list.add(String.valueOf(chars)); return; } else {
Set<Character> charSet = new HashSet<Character>(); for(int j=i;j<chars.length;j++) { if(i==j||!charSet.contains(chars[j])) {//这里唯一比较难理解的就是i==j,这里就是为了做一次无用功,先让后面的做全排列,以及对重复字符的处理。 charSet.add(chars[j]);
swap(chars,i,j); helper(chars,list,i+1); swap(chars,j,i); } } } } private void swap(char[] cs,int i,int j){ char temp = cs[i]; cs[i] = cs[j]; cs[j] = temp; }
利用全排列解决一些问题:
比如从1,2,3,4里面拿出3个数,组成不重复的
就是在退出的地方重新建一个数组,但只拿它的前n-1位
全组合:
public ArrayList<String> Comb(String str) { char[] chars = str.toCharArray(); ArrayList<String> list = new ArrayList<String>(); int combNum=1<<str.length(); for(int i=1;i<combNum;i++) { StringBuffer temp=new StringBuffer(); for(int j=0;j<str.length();j++) { int k=1<<j; if((k&i)!=0) { temp.append(chars[j]); } } if(!list.contains(temp.toString())) list.add(temp.toString()); } return list; }
打靶问题:
public int[] label= {0,1,2,3,4,5,6,7,8,9,10}; public void Compute(int score,int num,ArrayList<Integer> list){ if(score<0||score>(num+1)*10) return; if(num==0) { System.out.println(list); } for(int i=0;i<11;i++) { list.add(label[i]); Compute(score-label[i],num-1,list); list.remove(list.size()-1); } }
m个水果放到n个盘子里,问有多少种情况。重复的不算,和全组合是有点像的(5,1,1和1,1,5是同一种分法)
//m个水果放到n个盘子里面 public int fun(int m,int n) { if(m==0||n==1) return 1; if(n>m) return fun(m,m); else return fun(m,n-1)+fun(m-n,n);//第一个是有一个盘子不放水果,第二个是,每个盘子都放水果(先每个盘子都放一个,再去放其他的) } public int fun(int m,int n) { if(m==0||n==1) return 1; int[][] dp=new int[m+1][n+1]; for(int i=0;i<=n;i++) dp[0][i]=1; for(int j=0;j<=m;j++) dp[j][1]=1; for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { if(j<=i) dp[i][j]=dp[i][j-1]+dp[i-j][j];//和上面原理一样的,第一个是有一个盘子不放东西,第二个是所有盘子都放东西 else dp[i][j]=dp[i][i]; } } return dp[m][n]; }
本文来自博客园,作者:LeeJuly,转载请注明原文链接:https://www.cnblogs.com/peterleee/p/10560816.html

浙公网安备 33010602011771号