算法--猜字谜(哈希表优化)
作者:互联网
算法–猜字谜(哈希表优化)
元宵节的时候,力扣上的每日一题是这样的:
外国友人仿照中国字谜设计了一个英文版猜字谜小游戏,请你来猜猜看吧。 字谜的迷面 puzzle 按字符串形式给出,如果一个单词 word 符合下面两个条件,那么它就可以算作谜底:
单词 word 中包含谜面 puzzle 的第一个字母。
单词 word中的每一个字母都可以在谜面 puzzle 中找到。 例如,如果字谜的谜面是 “abcdefg”,那么可以作为谜底的单词有 “faced”,
“cabbage”, 和 “baggage”;而 “beefed”(不含字母 “a”)以及 “based”(其中的 "s"没有出现在谜面中)都不能作为谜底。
返回一个答案数组 answer,数组中的每个元素 answer[i] 是在给出的单词列表 words 中可以作为字谜迷面 puzzles[i] 所对应的谜底的单词数目。
- 示例: 输入: words =
[“aaaa”,“asas”,“able”,“ability”,“actt”,“actor”,“access”], puzzles =
[“aboveyz”,“abrodyz”,“abslute”,“absoryz”,“actresz”,“gaswxyz”]
输出:[1,1,3,2,4,0]
解释: 1 个单词可以作为 “aboveyz” 的谜底 : “aaaa”
1 个单词可以作为"abrodyz" 的谜底 : “aaaa”
3 个单词可以作为 “abslute” 的谜底 : “aaaa”, “asas”,“able”
2 个单词可以作为 “absoryz” 的谜底 : “aaaa”, “asas” 4 个单词可以作为 “actresz”
的谜底 : “aaaa”, “asas”, “actt”, “access” 没有单词可以作为 “gaswxyz”
的谜底,因为列表中的单词都不含字母 ‘g’。- 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/number-of-valid-words-for-each-puzzle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处*。
其中一种解法如下:哈希表特征码匹配法,子集使用深度优先搜索
(源代码没太仔细注释,本人试图注释一番,因为这位大佬的代码逻辑非常清楚,很适合他人学习。)
代码来源:力扣用户:verygoodlee
侵权必删
class Solution {
public List<Integer> findNumOfValidWords(String[] words, String[] puzzles) {
//创建哈希表
Map<Integer, Integer> map = new HashMap<>();
for (String word : words) { //遍历words字符数组
int key = 0;
for (char ch : word.toCharArray())
key |= 1 << ch - 'a';//把每个单词中每个字母ASCII码相加,再与1进行位或运算,生成独特的key值,|=按位或运算,<<左移ch-'a'位
//把相应的单词所代表的key存放进hash表,value统一为1.
map.put(key, map.getOrDefault(key, 0) + 1);
}
List<Integer> res = new ArrayList<>(puzzles.length);
for (String p : puzzles) { //遍历puzzles字符数组
char[] puzzle = p.toCharArray();
res.add(dfs(puzzle, 1, map, 1 << puzzle[0] - 'a'));// 首字符必选
}
return res;
}
public int dfs(char[] puzzle, int idx, Map<Integer, Integer> map, int key) {
if (idx == puzzle.length) return map.getOrDefault(key, 0);
// 首字符之外的字符可选可不选,两种情况
return dfs(puzzle, idx + 1, map, key) + dfs(puzzle, idx + 1, map, key | 1 << puzzle[idx] - 'a');
//前者dfs递归完毕直接返回 map.getOrDefault(1 << puzzle[0] - 'a',0),如果map中包含puzzle[0]头字母的key,则返回1,表示一个单词可以作为谜底
//后者dfs递归完puzzle中每一个字母,将puzzle中不重复出现的字母ASCII码值,获取了puzzle的key值,并使用map.getOrDefault(key,0),查找map中是否有相同的key,如果相同,返回value=1.
}
}
总结:
1.压缩状态,将word(模式串)的哈希值算出,并存放入map,value为1.
2.匹配哈希值,其中首字母必定选取,
标签:map,谜底,哈希,--,puzzle,puzzles,单词,猜字谜,words 来源: https://blog.csdn.net/weixin_44270165/article/details/114161510