[LeetCode] 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.

 

Note:

  1. licensePlate will be a string with length in range [1, 7].
  2. licensePlate will contain digits, spaces, or letters (uppercase or lowercase).
  3. words will have a length in the range [10, 1000].
  4. Every words[i] will consist of lowercase letters, and have length in range [1, 15].

 

這道題給了我們一個車牌號,還有一些單詞,讓我們找出包含這個車牌號中所有字母的第一個最短的單詞。車牌中的字母有大小寫之分,但是單詞只是由小寫單詞組成的,所以需要把車牌號中的所有大寫字母都轉為小寫的,轉換方法很簡單,ASCII碼加上32即可。我們建立車牌中各個字母和其出現的次數之間的映射,同時記錄所有字母的個數total,然后遍歷所有的單詞,對於每個單詞都要單獨處理,我們遍歷單詞中所有的字母,如果其在車牌中也出現了,則對應字母的映射減1,同時還需匹配的字母數cnt也自減1,最后遍歷字母完成后,如果cnt為0(說明車牌中所有的字母都在單詞中出現了),並且結果res為空或長度大於當前單詞word的話,更新結果即可,參見代碼如下:

 

解法一:

class Solution {
public:
    string shortestCompletingWord(string licensePlate, vector<string>& words) {
        string res = "";
        int total = 0;
        unordered_map<char, int> freq; 
        for (char c : licensePlate) {
            if (c >= 'a' && c <= 'z') {++freq[c]; ++total;}
            else if (c >= 'A' && c <= 'Z') {++freq[c + 32]; ++total;}
        }
        for (string word : words) {
            int cnt = total;
            unordered_map<char, int> t = freq;
            for (char c : word) {
                if (--t[c] >= 0) --cnt;
            }
            if (cnt == 0 && (res.empty() || res.size() > word.size())) {
                res = word;
            }
        }
        return res;
    }
}; 

 

如果這道題的單詞是按長度排序的話,那么上面的方法就不是很高效了,因為其會強制遍歷完所有的單詞。所以我們考慮給單詞排序,博主這里用了TreeMap這個數據結構建立單詞長度和包含所有該長度單詞的數組之間的映射,其會自動按照單詞長度來排序。然后還使用了一個chars數組來記錄車牌中的所有字母,這樣就可以方便的統計出字母總個數。我們從單詞長度等於字母總個數的映射開始遍歷,先檢驗該長度的所有單詞。這里檢驗方法跟上面略有不同,但都大同小異,用一個bool型變量succ,初始化為true,然后建立一個字母和其出現次數的映射,先遍歷單詞,統計各個字母出現的次數。然后就遍歷chars數組,如果chars中某個字母不在單詞中,那么succ賦值為false,然后break掉。最后我們看succ,如果仍為true,直接返回當前單詞word,之后的單詞就不用再檢驗了,參見代碼如下:

 

解法二:

class Solution {
public:
    string shortestCompletingWord(string licensePlate, vector<string>& words) {
        map<int, vector<string>> m;
        vector<char> chars;
        for (string word : words) {
            m[word.size()].push_back(word);
        }
        for (char c : licensePlate) {
            if (c >= 'a' && c <= 'z') chars.push_back(c);
            else if (c >= 'A' && c <= 'Z') chars.push_back(c + 32);
        }
        for (auto a : m) {
            if (a.first < chars.size()) continue;
            for (string word : a.second) {
                bool succ = true;
                unordered_map<char, int> freq;
                for (char c : word) ++freq[c];
                for (char c : chars) {
                    if (--freq[c] < 0) {succ = false; break;}
                }
                if (succ) return word;
            }
        }
        return "";
    }
};

 

參考資料:

https://discuss.leetcode.com/topic/114155/java-c-clean-code

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM