You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

64 lines
1.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class39;
// 来自百度
// 给定一个字符串str和一个正数k
// str子序列的字符种数必须是k种返回有多少子序列满足这个条件
// 已知str中都是小写字母
// 原始是取mod
// 本节在尝试上,最难的
// 搞出桶来,组合公式
public class Code03_SequenceKDifferentKinds {
// bu -> {6,7,0,0,6,3}
// 0 1 2 3 4 5
// a b c d e f
// 在桶数组bu[index....] 一定要凑出rest种来请问几种方法
public static int f(int[] bu, int index, int rest) {
if (index == bu.length) {
return rest == 0 ? 1 : 0;
}
// 最后形成的子序列一个index代表的字符也没有!
int p1 = f(bu, index + 1, rest);
// 最后形成的子序列一定要包含index代表的字符几个呢(所有可能性都要算上!)
int p2 = 0;
if (rest > 0) { // 剩余的种数,没耗尽,可以包含当前桶的字符
p2 = (1 << bu[index] - 1) * f(bu, index + 1, rest - 1);
}
return p1 + p2;
}
public static int nums(String s, int k) {
char[] str = s.toCharArray();
int[] counts = new int[26];
for (char c : str) {
counts[c - 97]++;
}
return ways(counts, 0, k);
}
public static int ways(int[] c, int i, int r) {
if (r == 0) {
return 1;
}
if (i == c.length) {
return 0;
}
// math(n) -> 2 ^ n -1
return math(c[i]) * ways(c, i + 1, r - 1) + ways(c, i + 1, r);
}
// n个不同的球
// 挑出1个的方法数 + 挑出2个的方法数 + ... + 挑出n个的方法数为:
// C(n,1) + C(n,2) + ... + C(n,n) == (2 ^ n) -1
public static int math(int n) {
return (1 << n) - 1;
}
public static void main(String[] args) {
String str = "acbbca";
int k = 3;
System.out.println(nums(str, k));
}
}