1255. 得分最高的单词集合
题目描述
给一个单词表words, 一个字母表letters
当用letters中的字母可以拼出words中的某个单词时,可以获得得分,
得分是按照字母来算的,每个字母得分在score数组中
提示:
- 单词表长度不大于14
- words和letters中只包含小写字母
- words中每个单词只能使用一次
- 每个字母的使用不能超过其在letter中的个数
f1-枚举子集+状态压缩 |
基本分析
- 由于字母不能超过对应的个数,怎么判断需要用当前字母合成哪些单词并计算得分?没有捷径,就是枚举凑哪些单词出来
- 怎么枚举凑哪些单词?用一个二进制数来表示状态,state从低位到高位分别表示第i个word是不是凑出来
- 怎么判断当前方案是不是可行?
- 需要定义一个字典,表示当前状态使用的字符的情况,如果超过了,就返回0;如果没有超过就计算得分
- 怎么维护这个字典?i在(0,n)中遍历,如果当前位i是1,就把words[i]对应的字符累加进去
- 怎么统计这个状态对应的得分?遍历d,对每个ch-v,分别计算得分并最终求和
- 怎么获取最终结果?
枚举每个结果,取最大值
代码
class Solution: def maxScoreWords(self, words: List[str], letters: List[str], score: List[int]) -> int: # 统计每个单词对应的字母情况 words_cnt = [Counter(word) for word in letters] letters_cnt = Counter(letters) n = len(words) @cache def dfs(state): d = dict() for i in range(n): if state >>i == 1: # 包含第i word for ch, v in words_cnt[i].items(): d[ch] = d.get(ch, 0) + v if d[ch] > letters_cnt[ch]: return 0 ans = sum([score[ord(ch)-ord('a')] * v for ch, v in d.items()]) return ans ans = max(dfs(i) for i in range(1, 1<<n)) return ans
复杂度
时间:待确定
空间:待确定
总结
- 这里每个单词都有两种可能,枚举了0-1<<n种可能
- 对每种可能计算能不能满足要求,能满足的计算得分
- 最终每种的得分取最大
- 还有比较快的f2-记忆化搜索+状态压缩的做法,待更新
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现