美文网首页
748. Shortest Completing Word

748. Shortest Completing Word

作者: Nancyberry | 来源:发表于2018-06-06 02:55 被阅读0次

    Description

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

    Solution

    题目有一些明显的坑:

    • 忽略非letter的character
    • letter ignore case
    • 要求返回the first word that meet restriction with smallest length

    大致思路还是很明确的,统计每个单词的count[],然后跟target need[]做比较。注意根据length更新result。

    HashTable, O(m + nL), S(1)

    class Solution {
        public String shortestCompletingWord(String licensePlate, String[] words) {
            if (licensePlate == null || licensePlate.isEmpty() || words == null || words.length == 0) {
                return "";
            }
            
            int[] need = new int[26];
            int totalNeed = 0;
            for (int i = 0; i < licensePlate.length(); ++i) {
                char c = licensePlate.charAt(i);
                if (!Character.isLetter(c)) {
                    continue;
                }
                ++need[Character.toLowerCase(c) - 'a'];
                ++totalNeed;
            }
            
            String res = "";
            
            for (String word : words) {
                if (word.length() < totalNeed) {    // prune
                    continue;
                }
                int[] have = new int[26];
                int stillNeed = totalNeed;
                
                for (int i = 0; i < word.length() && stillNeed > 0; ++i) {
                    char c = word.charAt(i);
                    if (!Character.isLetter(c)) {
                        continue;
                    }
                    int index = Character.toLowerCase(c) - 'a';
                    
                    if (++have[index] <= need[index]) {
                        --stillNeed;
                    }
                }
                
                if (stillNeed == 0 && (res.isEmpty() || word.length() < res.length())) {
                    res = word;
                }
            }
            
            return res;
        }
    }
    

    可以根据上面的解法,将方法抽象出来,这样看起来更清晰:

    class Solution {
        public String shortestCompletingWord(String licensePlate, String[] words) {
            if (licensePlate == null || licensePlate.isEmpty() 
                || words == null || words.length == 0) {
                return "";
            }
            
            int[] need = getCount(licensePlate);
            String res = "";
            
            for (String word : words) {
                int[] have = getCount(word);
                if (dominates(have, need) && (res.isEmpty() || word.length() < res.length())) {
                    res = word;
                }
            }
            
            return res;
        }
        
        private int[] getCount(String s) {
            s = s.toLowerCase();
            int[] count = new int[26];
            
            for (int i = 0; i < s.length(); ++i) {
                char c = s.charAt(i);
                if (!Character.isLetter(c)) {
                    continue;
                }
                ++count[c - 'a'];
            }
            
            return count;
        }
        
        private boolean dominates(int[] a, int[] b) {
            for (int i = 0; i < a.length; ++i) {
                if (a[i] < b[i]) {
                    return false;
                }
            }
            
            return true;
        }
    }
    

    相关文章

      网友评论

          本文标题:748. Shortest Completing Word

          本文链接:https://www.haomeiwen.com/subject/ccyvsftx.html