Leetcode每日一题记录 2.26
开个新坑,刷题找工作捏
力扣1255.得分最高的单词集合
你将会得到一份单词表 words,一个字母表 letters (可能会有重复字母),以及每个字母对应的得分情况表 score。
请你帮忙计算玩家在单词拼写游戏中所能获得的「最高得分」:能够由 letters 里的字母拼写出的 任意 属于 words 单词子集中,分数最高的单词集合的得分。
单词拼写游戏的规则概述如下:
1.玩家需要用字母表 letters 里的字母来拼写单词表 words 中的单词。
2.可以只使用字母表 letters 中的部分字母,但是每个字母最多被使用一次。
3.单词表 words 中每个单词只能计分(使用)一次。
4.根据字母得分情况表score,字母 ‘a’, ‘b’, ‘c’, … , ‘z’ 对应的得分分别为 score[0], score[1], …, score[25]。
5.本场游戏的「得分」是指:玩家所拼写出的单词集合里包含的所有字母的得分之和。
思路
用的是状态压缩,因为题目所给单词集合最大到14,也即子集最多为2^14个,遍历所有子集,算出每个合法子集(集合中的所有字母都能被字母集中的字母表示)所得的分数,然后取其最高分,子集的表示用的是状态压缩,也就是用一个int类型的变量来表示单词是否在本子集中。
例如:对于{“yes”,“no”,“ok”,“wow”,“hello”},其一个子集为{“yes”,“ok”,“hello”},那么我们用整数10101来表示这个子集
代码
参考了官方源码
class Solution {
public:
int maxScoreWords(vector<string>& words, vector<char>& letters, vector<int>& score) {
vector<int> count(26);
int n=words.size();
int res=0;
for(auto c : letters){//26位数组记录字母集中每个字母出现的次数
count[c-'a']++;
}
for(int s=1;s<(1<<n);s++){
vector<int> wordcount(26);
for(int j=0;j<n;j++){
if((s & (1<<j)) == 0) continue;//运算符优先级(笨比选手在这卡了好久)
for(auto c : words[j]){
wordcount[c-'a']++;//单词集中每个单词中字母出现的次数
}
}
bool ok=true;
int temp=0;
for(int k =0;k<26;k++){
temp+=wordcount[k]*score[k];
ok=ok && (wordcount[k]<=count[k]);
}
if(ok)
res=max(temp,res);//最大得分
}
return res;
}
};