全排和组合
使用递归
import java.util.ArrayList;
/**
* @Author: TJW
* @Description:
* @Date: 2018/12/5
*/
public class Ank_recursion {
public static void main(String[] args){
ArrayList<Integer[]> result = new ArrayList<>();
int list[]=new int[]{1,2,3};
perm(list,0,2,result);
for(int i=0;i<result.size();i++){
print(result.get(i));
}
}
//主要思路:分成0-s和s-e
public static void perm(int list[], int s, int e, ArrayList<Integer[]> result){
if(s>e){
result.add(copy(list));
}else{
for(int i=s;i<=e;i++){
swap(list,s,i);
perm(list,s+1,e,result);
swap(list,s,i);
}
}
}
/**
perm(list=[1,2,3],s=0;e=2;result[])
list=[1,2,3]
perm(list=[1,2,3],s=1;e=2;result[]) <----- \
list=[1,2,3] \
perm(list=[1,2,3],s=2;e=2;result[]) <-----\ \
list=[1,2,3] \ \
perm(list=[1,2,3],s=3;e=2;result[]) \ \
result=[{1,2,3}]; \ \
list=[1,2,3]-------------------------------\ \
liat=[1,2,3]-----------------------------------\
list=[1,3,2]
perm(list=[1,3,2],s=3;e=2;result[])
*/
public static void swap(int[] a, int x, int y){
int temp = a[x];
a[x] = a[y];
a[y] = temp;
}
public static Integer[] copy(int[] a){
Integer[] result = new Integer[a.length];
for(int i=0;i<a.length;i++){
result[i] = a[i];
}
return result;
}
public static void print(Integer[] a){
for(int i=0;i<a.length;i++){
System.out.print(a[i]);
}
System.out.println();
}
}
import java.util.ArrayList;
/**
* @Author: TJW
* @Description:
* @Date: 2018/12/6
*/
public class Cnk_recursion {
public static void main(String[] args) {
ArrayList<Integer[]> result = new ArrayList<>();
int list[]=new int[]{1,2,3,4};
int subset[]=new int[2];
combine(list,4,2,subset,result);
for(int i=0;i<result.size();i++){
print(result.get(i));
}
}
public static void combine(int s[],int n, int k, int subset[],ArrayList<Integer[]> result){
if(k==0){
result.add(copy(subset));
}else{
for(int i=n;i>=k;i--){
subset[k-1] = s[i-1];
combine(s,i-1,k-1,subset,result);
}
}
}
public static Integer[] copy(int[] a){
Integer[] result = new Integer[a.length];
for(int i=0;i<a.length;i++){
result[i] = a[i];
}
return result;
}
public static void print(Integer[] a){
for(int i=0;i<a.length;i++){
System.out.print(a[i]);
}
System.out.println();
}
}
非递归实现方法
import org.omg.Messaging.SYNC_WITH_TRANSPORT;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @Author: TJW
* @Description:
* @Date: 2018/12/6
*/
public class Ank {
public static void main(String[] args) {
Integer[] list = new Integer[]{1,2,3,4};
do {
for(int i=0;i<list.length;i++){
System.out.print(list[i]);
}
System.out.println();
}while (next_permutation(list));
}
/*
https://www.cnblogs.com/autosar/archive/2012/04/08/2437799.html
算法是:
(1) 从右向左,找出第一个比右边数字小的数字A。
(2) 从右向左,找出第一个比A大的数字B。
(3) 交换A和B。
(4) 将A后面的串(不包括A)反转。
*/
public static boolean next_permutation(Integer[] list){
int temp = list[list.length-1];
int indexA=-1,indexB=-1;
//第一个比temp小的为A
for(int i=list.length-1;i>=0;i--){
if(list[i]<temp){
indexA = i;
break;
}else{
temp = list[i];
}
}
if(indexA==-1){
return false;
}
//第一个比A大的为B
for(int i=list.length-1;i>=0;i--){
if(list[i]>list[indexA]){
indexB = i;
break;
}
}
if(indexB==-1){
return false;
}
//A<=>B
int tempAB = list[indexA];
list[indexA] = list[indexB];
list[indexB] = tempAB;
//A以后的翻转
for(int i=indexA+1;i<list.length-1;i++){
int tmp = list[i];
list[i] = list[i+1];
list[i+1] = tmp;
}
return true;
}
}
/**
* @Author: TJW
* @Description:
* @Date: 2018/12/6
*/
public class Cnk {
public static void main(String[] args) {
int[] list= new int[]{1,2,3,4};
combination(list,4,2);
}
/*
https://www.cnblogs.com/autosar/archive/2012/04/08/2437799.html
(1) 从左到右扫描0/1列表,如果遇到“10”组合,就将它转换为”01”.
(2) 将上一步找出的“10”组合前面的所有1全部移到set的最左侧。
(3) 重复(1) (2)直到没有“10”组合出现。
*/
public static void combination(int[] list, int n, int k){
int[] vec = new int[list.length];
for(int i=0;i<k;i++){
vec[i]=1;
}
for(int i=k;i<n;i++){
vec[i]=0;
}
boolean has_next = true;
while(has_next){
//print
for(int i=0;i<list.length;i++){
if(vec[i]==1){
System.out.print(list[i]);
}
}
System.out.println();
//calculate
has_next=false;
for(int i=0;i<list.length-1;i++){
if(vec[i]==1&&vec[i+1]==0){
vec[i]=0;
vec[i+1]=1;
int count = 0;
for(int j=0;j<i;j++){
if(vec[j]==1){
count++;
}
}
if(count<i){
for(int j=0;j<count;j++){
vec[j]=1;
}
for(int j=count;j<i;j++){
vec[j]=0;
}
}
has_next=true;
break;
}
}
}
}
}
参考(一个使用C++的实现):https://www.cnblogs.com/autosar/archive/2012/04/08/2437799.html