zoukankan      html  css  js  c++  java
  • 回溯法求解集合的全排列

            回溯法: 分为迭代回归和递归回归,一个集合{1,2,3,4,5},那么它的全排列,是{1,2,3,4,5},{1,2,3,5,4}....., 共有 5!=120种。对回溯法控制流程的抽象描述。每个解都在X(1:n)中生成一个解,一经确定就立即输出。在X(l),…,X(k-l)已被选定的情况下,T(X(l), …,* X(k-1))给出X(k)的所有可能的取值。限界函数B(X(l),…,X(k)) 判断哪些元素X(k)满足隐式约束条件。伪代码如下:

      

    * int k,n ;int X[n];
    
      * k=1* while(k>=0) {
    *    while(a[k]<=n){
    *  if((X[1],…,X[k])是一条已抵达一答案结点的路径) {
    *  print(X[1],…,X[k])
     }else{
    * ++k;
    } //考虑下一个集合
    * else
    {
    a[k]=0;
    --k;
     } //回溯到先前的集合
    }
    }
    迭代回溯java代码如下:
    
     public static void main(String[] args) {
    
        int k = 0;
        int n = 5;
    
        int[] a = new int[5];
    
        int count = 0;
    
        while (k >= 0) {
    
            while(k < n && a[k] < n ){
    
                a[k] = a[k]+1;
    
                if(legal(a,k,a[k])){
                    if(k == 4){
                        for(int e : a){
                            System.out.print(e);
                        }
                        System.out.println();
                        count++;
                        System.out.println("count" + count);
                        break;
                    }else{
                        k++;
                    }
                }
            }
            //回溯
            a[k]=0;
            --k;
        }
    }
    
    //判断是否有重复的元素
    public static boolean legal(int[] a, int k, int n) {
    
        for (int i = 0; i < k; i++) {
            if (a[i] == n) {
                return false;
            }
        }
        return true;
    }

     输入的结构如下:

    count: 1:1 2 3 4 5 count: 2:1 2 3 5 4 count: 3:1 2 4 3 5 count: 4:1 2 4 5 3 count: 5:1 2 5 3 4 count: 6:1 2 5 4 3 count: 7:1 3 2 4 5 count: 8:1 3 2 5 4 count: 9:1 3 4 2 5 count: 10:1 3 4 5 2
    count: 11:1 3 5 2 4 count: 12:1 3 5 4 2 count: 13:1 4 2 3 5 count: 14:1 4 2 5 3 count: 15:1 4 3 2 5 count: 16:1 4 3 5 2 count: 17:1 4 5 2 3 count: 18:1 4 5 3 2 count: 19:1 5 2 3 4 count: 20:1 5 2 4 3
    count: 21:1 5 3 2 4 count: 22:1 5 3 4 2 count: 23:1 5 4 2 3 count: 24:1 5 4 3 2 count: 25:2 1 3 4 5 count: 26:2 1 3 5 4 count: 27:2 1 4 3 5 count: 28:2 1 4 5 3 count: 29:2 1 5 3 4 count: 30:2 1 5 4 3
    count: 31:2 3 1 4 5 count: 32:2 3 1 5 4 count: 33:2 3 4 1 5 count: 34:2 3 4 5 1 count: 35:2 3 5 1 4 count: 36:2 3 5 4 1 count: 37:2 4 1 3 5 count: 38:2 4 1 5 3 count: 39:2 4 3 1 5 count: 40:2 4 3 5 1
    count: 41:2 4 5 1 3 count: 42:2 4 5 3 1 count: 43:2 5 1 3 4 count: 44:2 5 1 4 3 count: 45:2 5 3 1 4 count: 46:2 5 3 4 1 count: 47:2 5 4 1 3 count: 48:2 5 4 3 1 count: 49:3 1 2 4 5 count: 50:3 1 2 5 4
    count: 51:3 1 4 2 5 count: 52:3 1 4 5 2 count: 53:3 1 5 2 4 count: 54:3 1 5 4 2 count: 55:3 2 1 4 5 count: 56:3 2 1 5 4 count: 57:3 2 4 1 5 count: 58:3 2 4 5 1 count: 59:3 2 5 1 4 count: 60:3 2 5 4 1
    count: 61:3 4 1 2 5 count: 62:3 4 1 5 2 count: 63:3 4 2 1 5 count: 64:3 4 2 5 1 count: 65:3 4 5 1 2 count: 66:3 4 5 2 1 count: 67:3 5 1 2 4 count: 68:3 5 1 4 2 count: 69:3 5 2 1 4 count: 70:3 5 2 4 1
    count: 71:3 5 4 1 2 count: 72:3 5 4 2 1 count: 73:4 1 2 3 5 count: 74:4 1 2 5 3 count: 75:4 1 3 2 5 count: 76:4 1 3 5 2 count: 77:4 1 5 2 3 count: 78:4 1 5 3 2 count: 79:4 2 1 3 5 count: 80:4 2 1 5 3
    count: 81:4 2 3 1 5 count: 82:4 2 3 5 1 count: 83:4 2 5 1 3 count: 84:4 2 5 3 1 count: 85:4 3 1 2 5 count: 86:4 3 1 5 2 count: 87:4 3 2 1 5 count: 88:4 3 2 5 1 count: 89:4 3 5 1 2 count: 90:4 3 5 2 1
    count: 91:4 5 1 2 3 count: 92:4 5 1 3 2 count: 93:4 5 2 1 3 count: 94:4 5 2 3 1 count: 95:4 5 3 1 2 count: 96:4 5 3 2 1 count: 97:5 1 2 3 4 count: 98:5 1 2 4 3 count: 99:5 1 3 2 4 count:100:5 1 3 4 2
    count:101:5 1 4 2 3 count:102:5 1 4 3 2 count:103:5 2 1 3 4 count:104:5 2 1 4 3 count:105:5 2 3 1 4 count:106:5 2 3 4 1 count:107:5 2 4 1 3 count:108:5 2 4 3 1 count:109:5 3 1 2 4 count:110:5 3 1 4 2
    count:111:5 3 2 1 4 count:112:5 3 2 4 1 count:113:5 3 4 1 2 count:114:5 3 4 2 1 count:115:5 4 1 2 3 count:116:5 4 1 3 2 count:117:5 4 2 1 3 count:118:5 4 2 3 1 count:119:5 4 3 1 2 count:120:5 4 3 2 1

      2.一个数组int[] a的取3个元素的全排列,假如int[] a = {-1,2,1,3};

      

    public static List<List<Integer>> threeSum3(int[] nums) {
        int size = nums.length;
        int i = 0;
        //存储排列的结果
        int[] result = new int[4];
      //store index
        int[] index = new int[4];
    
        index[0] = -1;
    
        int j = 1;
    
        while (i >= 0 && j > 0) {
    
            while (i < size && j < result.length && j > 0) {
    
                result[j] = nums[i];
    
                index[j] = i;
    
                if (legal(index,j,i)) {
    
                    if (j == index.length-1) {
    
                        List<Integer> temp = new ArrayList<>();
    
                        for (int k = 1; k < result.length; k++) {
                            temp.add(result[k]);
                        }
                        retList.add(temp);
                        temp = null;
                    }else {
                        j++;
                        i=-1;
                    }
                }
                i++;
            }
            j--; //回溯
            i = index[j]+1;
        }
        return retList;
    }
    /**
     *
     * @param index
     * @param j
     * @param k
     * @return
     */
    public static boolean legal(int[] index, int j,int k) {
    
        for (int i = 1;i < j; i++) {
    
            if (index[i] == k) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
    int nums[] = {-1, 2, 1};

    List<List<Integer>> list = threeSum3(nums);

    System.out.println(list);

    System.out.println(list.size());
    }
     

    输入结果:

    [[-1, 2, 1], [-1, 1, 2], [2, -1, 1], [2, 1, -1], [1, -1, 2], [1, 2, -1]]
    6

     
  • 相关阅读:
    【转】为什么说面向对象编程和函数式编程都有问题
    【转】对博士学位说永别
    【转】写给支持和反对《完全用Linux工作》的人们
    【转】完全用Linux工作
    【转】人体工学
    【转】如何掌握所有的程序语言
    【转】Kotlin 和 Checked Exception
    【转】什么是现实理想主义者
    【转】经验和洞察力
    【转】C 编译器优化过程中的 Bug
  • 原文地址:https://www.cnblogs.com/xjz1842/p/5994033.html
Copyright © 2011-2022 走看看