这道题可以使用动态规划的方法来解决。首先,我们使用Counter来统计每个字母出现的次数。然后,定义一个二维数组f,其中f[i][j]表示使用前i个不同字母,组成长度为j的字符串的方法数。我们可以通过枚举前i-1个字母组成长度为j-c的字符串,然后从第i个字母中选出c个来组成长度为j的字符串,来更新f[i][j]。最后,将长度为1到n的所有字符串的方法数相加,得到最终结果。
时间复杂度: O(m*n^2)
空间复杂度: O(m*n)
class Solution:
def numTilePossibilities(self, tiles: str) -> int:
cnt = Counter(tiles).values() # 统计每个字母出现的次数
n, m = len(tiles), len(cnt) # n是字符串长度,m是不同字符的数量
f = [[0] * (n + 1) for _ in range(m + 1)] # 初始化动态规划数组
f[0][0] = 1 # 空字符串的组合数为1
for i, k in enumerate(cnt, 1): # 枚举字符
for j in range(n + 1): # 枚举长度
for c in range(min(j, k) + 1): # 从第i个字符中选择c个组成j长度的字符串
f[i][j] += f[i - 1][j - c] * comb(j, c) # 更新动态规划数组
return sum(f[m][1:]) # 返回长度为1到n的所有字符串的方法数之和