当前位置: 首页 > 编程笔记 >

java数组排列组合问题汇总

司空兴为
2023-03-14
本文向大家介绍java数组排列组合问题汇总,包括了java数组排列组合问题汇总的使用技巧和注意事项,需要的朋友参考一下

面试或笔试中,多次遇到以下4个关于排列组合的手撕算法,这里做个笔记,方法日后查阅:

1. 无重复元素的数组,求全排列;
2. 有重复元素的数组,求全排列;
3. 无重复元素的数组,求组合【子集】;
4. 有重复元素的数组,求组合;

以上四类题,可以用统一的模板实现,如下所示:

/*
 *【组合&&排列】
 *把一个数组里的数组合全部列出,比如1和2列出来为1,2,12,21.
 *这个题目可以扩展成四个:
 *1.无重复数字的数组,求组合
 *2.有重复数字的数组,求组合
 *3.无重复数字的数组,求全排列
 *4.有重复数字的数组,求全排列
 *【通用思路(递归)】:
 *定义一个函数:从候选集candicate中选取一个组合prefix
 *每次从候选集candicate中remove一个数,并加入前缀prefix,打印prefix;
 *再递归从新的candicate中remove下一个数,并加入prefix
 *【对于重复的控制】
 *采用hashset保存prefix,打印之前,判断hashset中是否包含当前生成的prefix,
 *没有则打印,并加入hashset;有则不打印
 *【组合--》排列】
 *只需在打印前加一个判断:若候选集candicate为空,表示遍历完一次,生成一个排列,可打印
 */

package xh.offer.practice;

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

public class listAllGroup{
  public static void main(String[] args) {
    String [] array = {"1","2"};
    String [] repeate = {"1","2","1"};
    listAllGroup test = new listAllGroup();
    System.out.println("**********no repeate list*******");
    test.listAllNoRepeate(Arrays.asList(array),"");//初始化prefix = ""
    System.out.println("**********repeate list*******");
    HashSet<String> noRepeateSet = new HashSet<String>();
    test.listAllRepeate(Arrays.asList(repeate), "", noRepeateSet);
    System.out.println("**************no repeate premutation********************");
    test.premutationNoRepeate(Arrays.asList(array),"");
    System.out.println("*********************repeate premutation**********************");
    HashSet<String> repeateSet = new HashSet<String>();
    test.premutationRepeate(Arrays.asList(repeate),"", repeateSet);
  }
  //无重复的组合
  public void listAllNoRepeate(List<String> candicate,String prefix){ 
    if(prefix.length() != 0)
      System.out.println(prefix);//结果长度不为0,则打印输出该组合

    for(int i = 0;i < candicate.size();i++){
      //将list转换成linklist链表,方便操作
      List<String> tempList = new LinkedList<String>(candicate);
      //templist减少一个数字,并暂存templist中去除的数字
      String tempString = (String) tempList.remove(i);
      //递归
      listAllNoRepeate(tempList,prefix + tempString);
    }
  }

  //有重复的组合,加入hashset
  public void listAllRepeate(List<String> candicate,String prefix,HashSet<String> res){
    if(prefix.length() != 0 && !res.contains(prefix)){
      System.out.println(prefix);
      res.add(prefix);
    }

    for(int i = 0;i < candicate.size();i++){
      List<String> tempList = new LinkedList<String>(candicate);
      String tempString = tempList.remove(i);
      listAllRepeate(tempList, prefix+tempString, res);//递归
    }
  }

  //无重复的全排列,加入判断candicate.size() == 0
  public void premutationNoRepeate(List<String> candicate,String prefix){
    if(candicate.size() == 0){
      System.out.println(prefix);
    }

    for(int i = 0;i < candicate.size();i++){
      List<String> tempList = new LinkedList<String>(candicate);
      String tempString = tempList.remove(i);
      premutationNoRepeate(tempList,prefix+tempString);
    }
  }

  //有重复的全排列,加入hashset辅助判断输出
  public void premutationRepeate(List<String> candicate,String prefix,HashSet<String> res) {
    if(candicate.size() == 0 && !res.contains(prefix)){
      System.out.println(prefix);
      res.add(prefix);
    }

    for(int i = 0;i < candicate.size();i++){
      List<String> tempList = new LinkedList<String>(candicate);
      String tempString = tempList.remove(i);
      premutationRepeate(tempList, prefix+tempString, res);
    }  
  }

  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍java实现字符串排列组合问题,包括了java实现字符串排列组合问题的使用技巧和注意事项,需要的朋友参考一下 本文为大家介绍了java实现字符串排列组合问题,供大家参考,具体内容如下 组合: 要么选择长度为n的字符串中的第一个字符,那么要在其余的长度n-1的字符串中选择m-1个字符 要么不选择长度为n的字符串中的第一个字符,那么要在其余的长度n-1的字符串中选择m个字符 以上就是本文

  • 我做了一个代码,应该显示数组中元素排列的整个组合。 应该是什么: 123 213 231 132 312 321 但结果是这样的: 231 312 123 231 312 123 如何以应有的方式进行排列?

  • 排列 下一个排列 LeetCode - 31. 下一个排列 题目描述 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。 必须原地修改,只允许使用额外常数空间。 以下是一些例子,输入位于左侧列,其相应输出位于右侧列。 1,2,3 → 1,3,2 3,2,1 → 1,2,3 1,1,5

  • 问题内容: 我正在寻找Java的库,该库将生成集合的所有可能的顺序排列。我可以找到的唯一库是Google代码上的combinatoricslib。我很难相信这是唯一执行此操作的Java库,并且坦率地说,对此感到非常惊讶。 JDK,Apache Commons Math或另一个库中是否有提供相同功能的东西? 我很高兴使用combinatoricslib,除了我自己编写算法之外,我简直不敢相信这是唯一

  • a=[78,187,30] b=[78,186,185,25,30] c=[78,187,186,185,25,30] //想获得的结果 a=[1,2,3,4,5] b=[1,6,7,8,3,9,5] c=[1,2,6,7,8,3,4,9,5] //想获得的结果 a、b数组里面的值都是唯一的,怎么用js获得想要的值呢? 问了ChatGPT都没解决,它给的方法在控制台输出结果不一致,因为chatGP

  • 问题内容: 给定以下数据框 我想按的总和对分组()进行排序,然后按(不对)的值进行分组。所以基本上得到组的顺序 然后通过对/错,最终看起来像这样: 如何才能做到这一点? 问题答案: Groupby A: 在每个组中,对B求和,然后使用transform广播值。然后按B排序: 通过从上方传递索引来索引原始df。这将按B值的总和对A值重新排序: 最后,使用选项保留“ A”组中的“ C”值,以保留步骤1