zoukankan      html  css  js  c++  java
  • JAVA回溯实现全排列和组合

      JAVA不像C++有next_permutation函数可以方便实现全排列,因此需要自己实现。

      函数perm用于实现数组中由下标p到下标q之间元素的全排列。为了便于理解我们举例 nums为 1  2  3  4,对于这四个数字我们可以分为四类

      

     第一类为以1作为头部后面剩余的数字进行全排列,第二类以2作为头部后面剩余的数字进行全排列。如此类推。根据这种原理我们就可以写出一个递归过程。

     1 public class Permutations {
     2     public static List<List<Integer>> permute(int[] nums) {
     3         List<List<Integer>> res = new ArrayList<>();
     4         if(null==nums||nums.length==0){
     5             return res;
     6         }
     7         List<Integer> l0 = new ArrayList<>();
     8         l0.add(nums[0]);
     9         res.add(l0);
    10         for(int i=1;i<nums.length;++i){
    11             List<List<Integer>> new_ans = new ArrayList<List<Integer>>();
    12             for(int j=0;j<=i;++j){
    13                 for(List<Integer> l:res){
    14                     List<Integer> new_l = new ArrayList<Integer>(l);
    15                     new_l.add(j, nums[i]);
    16                     new_ans.add(new_l);
    17                 }
    18             }
    19             res = new_ans;
    20         }
    21         return res;
    22     }
    23     
    24     public static void main(String[] args) {
    25         int[] nums = {1,2,3};
    26         System.out.println(permute(nums));
    27     }
    28 }

    理解了上述的思路稍作修改我们就可以写出从1....n中的k个数字的组合,代码如下

     1 public class Combinations {
     2     public static List<List<Integer>> combine(int n, int k) {
     3         List<List<Integer>> res = new ArrayList<>();
     4         combine(res, new ArrayList<Integer>(), 1, n, k);
     5         return res;
     6     }
     7     
     8     public static void combine(List<List<Integer>> res,List<Integer> comb,int start,int n,int k){
     9         if(k==0){
    10             res.add(new ArrayList<Integer>(comb));
    11             return;
    12         }
    13         
    14         for(int i=start;i<=n;i++){
    15             comb.add(i);
    16             combine(res, comb, i+1, n, k-1);
    17             comb.remove(comb.size()-1);
    18         }
    19     }
    20     
    21     public static void main(String[] args) {
    22         List<List<Integer>> res = combine(5, 2);
    23         System.out.println(res);
    24     }
    25 }
  • 相关阅读:
    后端解决跨域
    常用JS验证函数
    Tomcat:IOException while loading persisted sessions: java.io.EOFException解决手记
    js常用小功能示例
    软件开发五个阶段
    子类异常、访问权限与父类的关系
    什么时候需要使用try-catch
    java中的容器组件和非容器组件
    main方法必须是public static void main(String[] args)
    创建线程的方法
  • 原文地址:https://www.cnblogs.com/blzm742624643/p/10310354.html
Copyright © 2011-2022 走看看