[Algorithm] 排列组合相关问题
带有重复元素的全排列组合数问题
问题简单归纳: 给定n个字符(字符可重复),求n个字符不重复的全排列总数:
LeetCode 第94场双周赛第四题-统计同位异构字符串数目
解法:
- 对于n个字符的字符串,统计每个元素的数量
- 每次取出一个元素其数量为m,对n个字符的m个位置进行染色,即有comb(n,m)种组合方式,更新剩余位置n为n-m
- 不断重复2步骤直至每种元素都被枚举。
代码实现:
class Solution:
def countAnagrams(self, s: str) -> int:
mod = 1000000007
ans = 1
for t in s.split():
p = 1
n = len(t)
for k,v in Counter(t).items():
p = (p*comb(n,v)) % mod
n -= v
ans = (ans * p) % mod
return ans
二分组的组合问题
问题的简单描述:求将一个数组分为两个数组,每个数组的和都大于等于k
LeetCode 325场周赛 - 好分区的数目
思路:
由于k的范围只有1000,用01背包统计[0,k]区间的第一个背包所有组合情况,和超过k的记为k,取得第一个背包满足和大于k的组合数dp[k],之后再减去第二个背包不满足的组合数目即sum(dp[0...k-1])
代码实现:
class Solution:
def countPartitions(self, nums: List[int], k: int) -> int:
mod = 1000000007
s = sum(nums)
dp = [0] * (k+1)
dp[0] = 1
# sum, count
for i in range(len(nums)):
for j in range(k,-1,-1):
dp[min(j+nums[i],k)] = dp[min(j+nums[i],k)] + dp[j]
for i in range(k):
dp[k] = dp[k] - dp[i]
if dp[k]<0:
return 0
return dp[k] % mod

浙公网安备 33010602011771号