Loading

[Algorithm] 排列组合相关问题

带有重复元素的全排列组合数问题

问题简单归纳: 给定n个字符(字符可重复),求n个字符不重复的全排列总数:
LeetCode 第94场双周赛第四题-统计同位异构字符串数目
解法:

  1. 对于n个字符的字符串,统计每个元素的数量
  2. 每次取出一个元素其数量为m,对n个字符的m个位置进行染色,即有comb(n,m)种组合方式,更新剩余位置n为n-m
  3. 不断重复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
posted @ 2022-12-27 12:01  minskiter  阅读(33)  评论(0)    收藏  举报