排列与组合

摘要:排列组合,考察递归和回溯思想的运用

全排列

import java.util.*;
public class HelloWorld {
    /**
     *  递归求全排列
     */
    static int[] arr = new int[]{1,2,3};
    
    
	static List<List<Integer>> res = new ArrayList<>(); 
	
    public static void main (String[] args) {
        permute(arr);
        System.out.println(res);
    }
	
static List<List<Integer>> permute(int[] arr ){
	    if(arr.length == 0){
	        return res;
	    }
	    List<Integer> temp = new ArrayList<>();
	    generatePurmutation2(arr,0,temp);
	    
	    return res;
    
}
	
static void swap(int i,int j){
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
//交换回溯法
// begin 逐个考察,而 j 是工作指针进行交换
static void generatePurmutation(int[] arr,int begin,List<Integer> temp){
    // 当begin指向最后一个元素时,此时已经可以结束了
    if(begin == arr.length-1){
        for (int i =0;i<arr.length ;i++ ){
            temp.add(arr[i]);
        } 
        res.add(new ArrayList<Integer>(temp));
        temp.clear();
        return ;
    }
    
    for (int j=begin;j<=arr.length-1;j++){
        swap(begin,j);
        
        generatePurmutation(arr,begin+1,temp);
        swap(begin,j); //回溯需要交换到原始状态
    } 
	return ;
}
// 全考察剪支法
// 借用一个used数组存储已选的元素
static boolean[] used  = new boolean[arr.length];

static void generatePurmutation2(int[] arr,int begin,List<Integer> temp){
    if(begin == arr.length){
        res.add(new ArrayList<Integer>(temp));
        return ;
    }
    //全考察
    for (int i = 0 ;i< arr.length ;i++ ){
        if(!used[i]){ //此处判断就是为了剪支
            temp.add(arr[i]);
            used[i] =true;
            generatePurmutation2(arr,begin+1,temp);
            //回溯 
            used[i] =false;
            temp.remove(temp.size()-1);
        }   
    } 
}
}

求组合

import java.util.*;
public class HelloWorld {
	public static void main(String[] args) {
	
		res = combine(4,2);
		System.out.println(res);
	}
	
	static List<List<Integer>> res = new ArrayList<>();
	
	static List<List<Integer>> combine(int n,int k){
	    if(n<0|| k<0|| k>n){
	        return res;
	    }
	    List<Integer>  c = new ArrayList<>();
	    generateCombination(n,k,1,c);
	    return res;
	    
	}

求子集回溯法

	static void generateCombination(int n,int k,int start,List<Integer> temp){
	    if(temp.size() == k ){
	        res.add(new ArrayList<Integer>(temp));
	        return ;
	    }
	    if(start>4){ //求子集法,需要加限制条件,不然会爆
	        return ;
	    }
	   // for (int i=start;i<= n ;i++ ){
	        int i = start;
	        temp.add(i);
	        generateCombination(n,k,i+1,temp);
	        temp.remove(temp.size()-1);
	        generateCombination(n,k,i+1,temp);
	   // } 
	    
	}

循环回溯法

	static void generateCombination(int n,int k,int start,List<Integer> temp){
	    if(temp.size() == k ){
	        res.add(new ArrayList<Integer>(temp));
	        return ;
	    }
	    for (int i=start;i<= n ;i++ ){
	        
	        temp.add(i);
	        generateCombination(n,k,i+1,temp);
	        temp.remove(temp.size()-1);
	       // generateCombination(n,k,i+1,temp);
	    } 
	    
	}
posted @ 2021-04-07 07:36  Realization  阅读(50)  评论(0编辑  收藏  举报