Shortest Completing Word

easy string hash map counting

Problem

Given a licence plate string and an array of words, return the shortest word that contains all letters (ignoring case and digits) of the plate. Ties go to the earliest such word.

Inputplate="1s3 PSt", words=["step","steps","stripe","stepple"]
Output"steps"
Both "step" and "steps" cover the letters, but step is missing an extra s; steps wins as shortest.

def shortestCompletingWord(licensePlate, words):
    from collections import Counter
    need = Counter(c.lower() for c in licensePlate if c.isalpha())
    best = None
    for w in words:
        wc = Counter(w)
        if all(wc[c] >= n for c, n in need.items()):
            if best is None or len(w) < len(best): best = w
    return best
function shortestCompletingWord(plate, words) {
  const need = {};
  for (const c of plate.toLowerCase()) if (c >= 'a' && c <= 'z') need[c] = (need[c] || 0) + 1;
  let best = null;
  for (const w of words) {
    const have = {};
    for (const c of w) have[c] = (have[c] || 0) + 1;
    let ok = true;
    for (const c in need) if ((have[c] || 0) < need[c]) { ok = false; break; }
    if (ok && (best === null || w.length < best.length)) best = w;
  }
  return best;
}
class Solution {
  public String shortestCompletingWord(String plate, String[] words) {
    int[] need = new int[26];
    for (char c : plate.toLowerCase().toCharArray()) if (c >= 'a' && c <= 'z') need[c - 'a']++;
    String best = null;
    for (String w : words) {
      int[] have = new int[26];
      for (char c : w.toCharArray()) have[c - 'a']++;
      boolean ok = true;
      for (int i = 0; i < 26; i++) if (have[i] < need[i]) { ok = false; break; }
      if (ok && (best == null || w.length() < best.length())) best = w;
    }
    return best;
  }
}
class Solution {
public:
  string shortestCompletingWord(string plate, vector<string>& words) {
    int need[26] = {0};
    for (char c : plate) if (isalpha(c)) need[tolower(c) - 'a']++;
    string best;
    for (auto& w : words) {
      int have[26] = {0};
      for (char c : w) have[c - 'a']++;
      bool ok = true;
      for (int i = 0; i < 26; i++) if (have[i] < need[i]) { ok = false; break; }
      if (ok && (best.empty() || w.size() < best.size())) best = w;
    }
    return best;
  }
};
Time: O(N * L) Space: O(1)