具体题目要求请看https://leetcode.com/contest/weekly-contest-162/problems/maximum-score-words-formed-by-letters/
下边敷衍的放一张题目的图片:
题目说明:
26个英文小写字母都有自己的分数score[i],你可以从letters挑选任意一些组成words中的单词,你获得的分数就是我使用letters中的字符对应的score,要求获得最大的分数;
思路:
这在hard级别的题目中是较为简单的,总体来讲是遍历(暴力解法)用dfs,对于words中的单词,每个单词都有被选中和不被选中两种可能,如果words长度为n,那么时间复杂度就是(2^n);
首先要获得一个letters中单词与数量的表valid[c],举个例子,对于letters = ["a","a","c","d","d","d","g","o","o"],有valid['a']=2, valid['c'] = 1, valid['d'] = 3.......等等,在dfs的过程中维护一个最小的ans;
下边是代码:
class Solution {
public:
void solve(vector<string>& words, vector<int>& score,int cur,int n,int tot,int&ans,vector<int>&valid){
if(cur==n){
ans = max(ans,tot);
return;
}
solve(words,score,cur+1,n,tot,ans,valid);
for(auto c:words[cur]){
valid[c-'a']--;
tot+=score[c-'a'];
}
bool flag = true;
for(int i = 0;i<26;i++)
if(valid[i]<0)
flag = false;
if(flag){
solve(words,score,cur+1,n,tot,ans,valid);
}
for(auto c:words[cur]){
valid[c-'a']++;
tot-=score[c-'a'];
}
}
int maxScoreWords(vector<string>& words, vector<char>& letters, vector<int>& score) {
int n = words.size();
int ans = 0;
vector<int>valid(26,0);
for(auto c:letters)
valid[c-'a']++;
solve(words,score,0,n,0,ans,valid);
return ans;
}
};
在solve函数中,tot是当前的分数,cur代表是words的第cur个元素,cur==n是截止条件,如果不选择当前的words,直接cur+1带入solve,如果选择当前的words,检验valid中字母的数量是否充足,flag==false说明字母数量不够
进行2^n后得到的ans即为最后结果