• 排列与组合


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

    全排列

    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);
    	    } 
    	    
    	}
    
  • 相关阅读:
    pch文件的创建
    常用的Xcode插件下载地址
    内存管理
    学习笔记-static的作用
    IOS 之label的自适应
    OC中的循环引用
    理解事务的4种隔离级别
    Solrcloud集群搭建
    常见前端浏览器兼容问题及解决方案
    Java内存溢出详解及配置
  • 原文地址:https://www.cnblogs.com/Qvolcano-blog/p/14619149.html
Copyright © 2020-2023  润新知