leetcode 1079. 活字印刷
你有一套活字字模 tiles,其中每个字模上都刻有一个字母 tiles[i]。返回你可以印出的非空字母序列的数目。
注意:本题中,每个活字字模只能使用一次。
示例 1:
输入:"AAB"
输出:8
解释:可能的序列为 "A", "B", "AA", "AB", "BA", "AAB", "ABA", "BAA"。
示例 2:
输入:"AAABBC"
输出:188
提示:
1 <= tiles.length <= 7
tiles 由大写英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/letter-tile-possibilities
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
1:统计length 个字符可排列组合而成的字符串,可用 n = 1 * 2 * 3 * ... * (length - 1) * length 。
2:若是其中有重复的字符,需要除去重复的字符串,
m = 1 * 2 * 3 * ... * (c - 1) * c (c个重复的某字符串) * [同理,每个重复的字符串的个数都如此计算。]
例如 AAABBC 6 * 5 * 4 * 3 * 2 * 1 / (1 * 2 * 3 * 1 * 2) = 60 个
3:递归遍历,每个字符减少一个以后,所组成的字符,最后相加,即为所求。
4:因为字符都是大写,可用数组来记录其出现的次数。
int sum = 0; public int numTilePossibilities(String tiles) { int length = tiles.length() ; int[] arr = new int[26]; for (int i = 0; i < length; i++) { arr[tiles.charAt(i) - 'A']++; } find(arr, length, 0); return sum; } private void find (int[] arr, int n, int index) { if (n == 1) { sum++; return; } if (n > 0) { int a = 1; int b = 1; for (int i = 2; i <= n; i++) { a *= i; } for (int value : arr) { if (value > 1) { for (int i = 2; i <= value; i++) { b *= i; } } } sum += (a / b); for (int i = index; i < 26; i++) { int value = arr[i]; if (value > 0) { arr[i]--; find (arr, n - 1, i ); arr[i]++; } } } }