zoukankan      html  css  js  c++  java
  • 排列与组合

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

    全排列

    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);
    	    } 
    	    
    	}
    
  • 相关阅读:
    过滤器--起步阶段
    常用指令-起步阶段
    模型和控制器-起步阶段
    指令介绍-起步阶段
    AngularJS简介-起步阶段
    c++之helloworld与命名空间
    c++ 之重要性
    一个没曾摸透的程序
    linux中什么是文件结构体?
    很全的linux网络编程技巧
  • 原文地址:https://www.cnblogs.com/Qvolcano-blog/p/14619149.html
Copyright © 2011-2022 走看看