748. Shortest Completing Word。

Find the minimum length word from a given dictionary words, which has all the letters from the string licensePlate. Such a word is said to complete the given string licensePlate

Here, for letters we ignore case. For example, “P” on the licensePlate still matches “p” on the word.

It is guaranteed an answer exists. If there are multiple answers, return the one that occurs first in the array.

The license plate might have the same letter occurring multiple times. For example, given a licensePlate of “PP”, the word “pair” does not complete the licensePlate, but the word “supper” does.

Example 1:

Input: licensePlate = “1s3 PSt”, words = [“step”, “steps”, “stripe”, “stepple”]
Output: “steps”
Explanation: The smallest length word that contains the letters “S”, “P”, “S”, and “T”.
Note that the answer is not “step”, because the letter “s” must occur in the word twice.
Also note that we ignored case for the purposes of comparing whether a letter exists in the word.

Example 2:

Input: licensePlate = “1s3 456”, words = [“looks”, “pest”, “stew”, “show”]
Output: “pest”
Explanation: There are 3 smallest length words that contains the letters “s”.
We return the one that occurred first.

原文:https://leetcode.com/problems/shortest-completing-word/description/


题中会给两个字符串,第一个字符串是licensePlate,其中包含了一些字符。第二个字符串是words是,其中是一些单词。我们需要做的就是在第一个字符串licensePlate中找出所有的字母(大小写都算),然后需要在第二个字符串中words中找出某个单词,这个需要单词包含licensePlate中所有出现的字母。并且在所有满足条件的单词中找出长度最小的那个单词,如果出现长度相等的情况则返回第一个。


这个题貌似没有特别神奇的解法,我的做法是先找出licensePlate中的所有字母,并将字母转换成小写存放在一个数组中。然后开始遍历单词,对于每个单词都需要先将其拆分为字母然后存放在一个hash表中,hash表的key是单词的中出现的字母,对应的value是每个字母出现的次数。

然后再次遍历licensePlate中的所有字母,并且在hash表中查找这些字母,如果出现了某个字母对应的value为0,则说明单词中没有出现该字母,则不符合条件。如果某个字母出现过一次,则将对应为value减去一。最后还需要比较一下单词的长度,得到最终结果。

class Solution {
public:
    string shortestCompletingWord(string licensePlate, vector<string>& words) {
        int minLengthIndex = 0;
        vector<char> license;// 用来存放licensePlate中共有多少个字母
        unordered_map<char,int> word;// 用来存放单词拆解之后的字母
        int minLength = INT_MAX;// 用力记录最小的单词位置
        int curLength = 0;// 用来记录当前单词的长度
        int isExist = true;

        for(char ch : licensePlate) {
            ch = tolower(ch);// 将其变为小写
            if(ch >= 'a' && ch <= 'z') {// 属于字母范围内
                license.push_back(ch);
            }
        }

        for(int i=0;i<words.size();i++) {
            curLength = 0;
            isExist = true;
            word.clear();// 清空
            for(char ch : words[i]) {// 将单词拆解开来存入hash表中
                curLength++;
                ch = tolower(ch);
                word[ch]++;
            }
            for(char ch : license) {// 遍历licensePlate的所有字母
                if(word[ch]-- == 0) {// 说明这个字母在单词中没有出现过
                    isExist = false;// 不存在
                    break;// 结束循环
                }
            }

            if(isExist) {// 如果存在则比较长度
                if(curLength < minLength) {
                    minLength = curLength;
                    minLengthIndex = i;
                }
            }
        }
        return words[minLengthIndex];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值