排列组合Java代码实现(重复字符串与不重复字符串)

package LanQiao.day06;

/**
 * @program: ShuJuJieGou
 * @author: GONG-Q
 * @create: 2021-10-13 18:17
 **/
public class 排列 {
    //不重复的字符串的全排列
    public static void string_full_permutation(String str,StringBuffer buffer){
        //结束条件
        if(buffer.length()==str.length()){
            System.out.println(buffer.toString());
            return;
        }
        //递归体的部分
        for (int i = 0; i < str.length(); i++) {
            //判断是否重 一次只能有一个
            if(buffer.toString().indexOf(str.charAt(i))!=-1) continue;  //如果找到了就说明已经存在过了所以删除
            buffer.append(str.charAt(i));
            string_full_permutation(str,buffer);
            buffer.deleteCharAt(buffer.length()-1);
        }
    }

    //有重复的字符串的排列

    /**
     * 对于有重复的算法来说 很重要的一点就是首先要对传入的进行排序 这样的话更好筛选 如果这一位与上一位相同那么必定就是重复的需要减枝
     * 因为有重复的 不能用一般的条件来判断是不是已经访问过了 所以需要使用的是一个数组来表示这个点是否被访问过
     * 也不要忘记进行回溯
     * @param repeatStr
     * @param buffer
     * @param visit
     */
    public static void repeat_string_permutation(String repeatStr,StringBuffer buffer,boolean[] visit){
        if(repeatStr.length()==buffer.length()){
            System.out.println(buffer.toString());
            return;
        }

        for (int i = 0; i < repeatStr.length(); i++) {
         //  if(buffer.toString().indexOf(repeatStr.charAt(i))!=-1) continue;
            if(visit[i]==true) continue;
            //因为有重复的元素 所以需要减枝操作
            if(i-1>=0&&repeatStr.charAt(i)==repeatStr.charAt(i-1)&&!visit[i-1]) continue;
            buffer.append(repeatStr.charAt(i));
            visit[i]=true;
            repeat_string_permutation(repeatStr,buffer,visit);
            buffer.deleteCharAt(buffer.length()-1);
            visit[i]=false;
        }
    }

    //组合的算法

    /**
     *
     * @param n  需要组合的
     * @param k   需要组合的数量
     * @param start  开始的位置
     * @param buffer  存放结果
     */
    public static void combine(int n,int k,int start,StringBuffer buffer){
        if(k==0){
            System.out.println(buffer.toString());
            return;
        }
        //递归的部分
        for (int i = start; i <= n; i++) {
            buffer.append(i);
            combine(n,k-1,i+1,buffer);
            buffer.deleteCharAt(buffer.length()-1);
        }
    }


    public static void main(String [] args){
     //   string_full_permutation("ABC",new StringBuffer());
      //  repeat_string_permutation("aab",new StringBuffer(),new boolean[3]);
        combine(4,2,1,new StringBuffer());
    }
}

还有另外一种方式:
就是通过swap的方式也可以进行排列

package LanQiao.day06;

import java.util.List;
import java.util.Vector;

/**
 * @program: ShuJuJieGou
 * @author: GONG-Q
 * @create: 2021-10-13 16:17
 *
 * 由不同字母构成的串 求全排
 **/
public class 排列组合 {
    public static void main(String [] args){
        String s="ABD";
        System.out.println(full_permutation(s));
    }


    /**
     * 字符数组的排列方式
     * @param chars
     * @param a
     * @param b
     */
    public static void paiLie(char[] chars,int a,int b){
        //递归结束条件就是排序的串只有一个字母的时候
        if(a==b){
            for (int i = 0; i < chars.length; i++) {
                System.out.print(chars[i]);
            }
        }
        //递归部分
        for (int i = a; i < b; i++) {
            swap(chars,a,i);
            paiLie(chars,a+1,b);
            swap(chars, a, i);
        }

    }


    //交换函数
    public static void swap(char[] a,int i,int j){
        char temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }

    //字符串的排列方式
    public static List<String> full_permutation(String str){
        List<String> List = new Vector<>();
        //通过字符串的方式
        if(str.length()==1){
            List.add(str);
            return List;
        }
        //递归体的部分
        for (int i = 0; i < str.length(); i++) {
            char cur = str.charAt(i);//用于临时存放

            //再创建一个用于存放除去I的之外的排列
            List<String> list = new Vector<>();
            list=full_permutation(str.substring(0,i)+str.substring(i+1));
            //然后将I加到前面
            for (int j = 0; j < list.size(); j++) {
                List.add(""+cur+list.get(j));
            }
        }
        return List;
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值