题目
你将会得到一份单词表 words,一个字母表 letters (可能会有重复字母),以及每个字母对应的得分情况表 score。
请你帮忙计算玩家在单词拼写游戏中所能获得的「最高得分」:能够由 letters 里的字母拼写出的 任意 属于 words 单词子集中,分数最高的单词集合的得分。
单词拼写游戏的规则概述如下:
-
玩家需要用字母表 letters 里的字母来拼写单词表 words 中的单词。
-
可以只使用字母表 letters 中的部分字母,但是每个字母最多被使用一次。
-
单词表 words 中每个单词只能计分(使用)一次。
-
根据字母得分情况表score,字母 ‘a’, ‘b’, ‘c’, … , ‘z’ 对应的得分分别为 score[0], score[1], …, score[25]。
-
本场游戏的「得分」是指:玩家所拼写出的单词集合里包含的所有字母的得分之和。
思路
- 遍历字母表 letters,统计每个字符出现的次数。
- 遍历单词表 words,统计每个单词的得分。
- 对于每个单词,判断字母表 letters 中是否包含单词中的每个字符,如果包含则继续判断字母表 letters
中每个字符的数量是否大于等于单词中该字符的数量。 - 如果字母表 letters 中包含单词中的所有字符并且每个字符的数量都不小于单词中该字符的数量,则计算该单词的得分。
- 在所有满足条件的单词中找到得分最高的一个,返回该得分。
解题代码
class Solution {
public int max;
public int maxScoreWords(String[] words, char[] letters, int[] score) {
int[] lettersCnt = new int[26];
for(int i = 0; i < letters.length; i++){
lettersCnt[letters[i] - 'a'] ++;
}
int[] wordsScore = new int[words.length];
for(int i = 0; i < words.length; i++){
int sum = 0;
for(int j = 0; j < words[i].length(); j++ ){
char c = words[i].charAt(j);
sum += score[c - 'a'];
}
wordsScore[i] = sum;
}
dfs(lettersCnt, wordsScore, words, 0, 0);
return max;
}
public void dfs(int[] lettersCnt, int[] wordsScore,String[] words, int index,int res ){
for(int i = index; i < words.length ; i++){
//从字母表删除对应字母数目,如果有小于0 的不成立
if(check(lettersCnt, words[i], -1)){
dfs(lettersCnt, wordsScore, words, i + 1, res + wordsScore[i]);
}
//回溯,从字母表加回去
check(lettersCnt, words[i], 1);
}
max = Math.max(max, res);
}
public boolean check(int[] lettersCnt, String words, int m){
boolean flag = true;
for(int i = 0 ; i < words.length(); i ++){
lettersCnt[words.charAt(i) - 'a'] += m;
if(lettersCnt[words.charAt(i) - 'a'] < 0){
flag = false;
}
}
return flag;
}
}