构成指定长度字符串的个数

题目描述:构成指定长度字符串的个数
给定 M(0 < M ≤ 30)个字符(a-z),从中取出任意字符(每个字符只能用一次)拼接成长度为 N(0 < N ≤ 5)的字符串,

要求相同的字符不能相邻,计算出给定的字符列表能拼接出多少种满足条件的字符串,

输入非法或者无法拼接出满足条件的字符串则返回0。

输入描述
给定的字符列表和结果字符串长度,中间使用空格(" ")拼接

输出描述
满足条件的字符串个数

用例1
输入

aab 2
输出

2
说明

只能构成ab,ba。

用例2
输入

abc 2
输出

6
说明

可以构成:ab ac ba bc ca cb 。

解题思路
使用递归和回溯的思想来生成不同的字符串。具体的逻辑如下:

首先,我们定义一个函数generateDistinctStrings,这个函数接收以下参数:可用字符集s,目标字符串长度length,当前已生成的字符串current,已生成的结果集result,以及一个标记数组used,用来记录每个字符是否已被使用。

在generateDistinctStrings函数中,首先检查当前已生成的字符串current的长度是否等于目标长度length。如果等于,说明我们已经生成了一个满足长度要求的字符串,将其添加到结果集result中,然后返回。

如果当前字符串current的长度还未达到目标长度length,我们就需要继续添加字符。此时,我们遍历可用字符集s中的每一个字符。对于每一个字符,我们首先检查它是否已经被使用(通过查看used数组),以及它是否与current的最后一个字符相同。如果字符已经被使用,或者与前一个字符相同,则跳过当前拼接。

public static int appendSonString() {
int count = 0;
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine();
String[] arrIntStr = line.split(" ");

    // 0<n<=5
    int n = Integer.parseInt(arrIntStr[1]);
    String s = arrIntStr[0];
    // 所有的字符
    String[] arr = s.split("");
    int arrlen = arr.length;

    Pattern compile = Pattern.compile("[^a-z]");
    if (arrlen < n || compile.matcher(s).find()) {
        // 非 a-z 字母
        return 0;
    } else {
        count = countDistinctString(s, n);
    }
    return count;
}

// 递归 组成 字符串
private static void generateDistinctStrings(String s, int length, String current, Set<String> result, boolean[] used) {

    // 字符串 组合 完成
    if (length == current.length()) {
        result.add(current);
        return;
    }

    for (int i = 0; i < s.length(); i++) {
        // 如果字符已被使用,或者字符与前一个字符相同,则跳过
        if (used[i] || (current.length() > 0 && current.charAt(current.length() - 1) == s.charAt(i))) {
            continue;
        }
        used[i] = true;

        // 递归 发散
        generateDistinctStrings(s, length, current + s.charAt(i), result, used);

        // s的第i位结束后,i可以继续使用
        used[i] = false;
    }
}

private static int countDistinctString(String s, int length) {
    Set<String> distinctStrings = new HashSet<>();
    boolean[] used = new boolean[s.length()];
    generateDistinctStrings(s, length, "", distinctStrings, used);
    return distinctStrings.size();
}
posted @   vello  阅读(123)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示