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]++;
                }
            }
        }
    }

posted @ 2021-08-14 21:31  旺仔古李  阅读(154)  评论(0编辑  收藏  举报