题目来源于力扣(LeetCode)
一、题目
题目相关标签:哈希表
提示:
- 牌照(licensePlate)的长度在区域[1, 7]中。
- 牌照(licensePlate)将会包含数字、空格、或者字母(大写和小写)。
- 单词列表(words)长度在区间 [10, 1000] 中。
- 每一个单词 words[i] 都是小写,并且长度在区间 [1, 15] 中。
二、解题思路
-
对 licensePlate 字符串中的字母字符元素进行哈希映射,键为字母对应的索引,值为字母出现的次数
-
遍历 words 数组,对于数组中的每个元素也进行哈希映射
-
两个哈希映射的数组进行次数的比较,当前遍历单词的哈希映射包含了 licensePlate 中的全部字母字符时,说明该单词可能为完整词
-
当前遍历的单词为完整词且字符串长度小于已记录的最短完整词长度时,当前单词成为新的最短完整词
三、代码实现
public static String shortestCompletingWord(String licensePlate, String[] words) {
int[] letters = new int[26];
String ans = "";
// licensePlate 字符串中字母字符映射
letterMap(licensePlate, letters);
int len = Integer.MAX_VALUE;
for (int i = 0; i < words.length; i++) {
int[] wordLetters = new int[26];
String str = words[i];
// 长度大于等于最短完整词时,continue
if (str.length() >= len) {
continue;
}
// str 字符串中字母字符映射
letterMap(str, wordLetters);
for (int m = 0; m < letters.length; m++) {
// str 字符串中是否包含 licensePlate 中的全部字母字符
if (wordLetters[m] < letters[m]) {
break;
}
// 当前遍历字符串包含 licensePlate 中的全部字母字符,且字符串长度小于最短完整词的长度时
if (m == letters.length - 1 && str.length() < len) {
// 当前遍历字符串成为新的最短完整词,并修改长度
ans = str;
len = str.length();
}
}
}
return ans;
}
// 字符串中的字母字符映射到哈希数组中
public static void letterMap(String str, int[] arr) {
for (int i = 0; i < str.length(); i++) {
char j = str.charAt(i);
if (j >= 'A' && j <= 'Z') {
// 大写字母 + 32 成小写字母
arr[j + 32 - 'a'] += 1;
} else if (j >= 'a' && j <= 'z') {
arr[j - 'a'] += 1;
}
}
}
四、执行用时
五、部分测试用例
public static void main(String[] args) {
String licensePlate = "1s3 PSt";
String[] words = {"step", "steps", "stripe", "stepple"}; // output: "steps"
// String licensePlate = "1s3 456";
// String[] words = {"looks", "pest", "stew", "show"}; // output: "pest"
String result = shortestCompletingWord(licensePlate, words);
System.out.println(result);
}