Shortest Completing Word solution and explanation
9 more videos on this problem
花花酱 LeetCode 748. Shortest Completing Word - 刷题找工作 EP138Hua Hua · 8:29 · 2K views
748. Shortest Completing Word | Leetcode | PythonAbdullah Arshed · 5:21 · 1K views
LeetCode 748 | Shortest Completing Word | Counting Array | Debug | JavaSleepy Cracker · 10:19 · 920 views
748. Shortest Completing Word || LEETCODE SOLUTION || IN C++ || DATA STRUCTURE AND ALGORITHMAbhishweta Gupta · 3:58 · 847 views
LeetCode 748. Shortest Completing Word | JSer - JavaScript & AlgorithmJSer · 9:21 · 824 views
Shortest Completing Word #java #maps #strings #array #arraylist #javainterview #leetcodeCodeVia · 8:13 · 663 views
Leetcode [0749] Shortest Completing WordSDE Skills · 23:46 · 605 views
748. Shortest Completing Word (Leetcode Easy)Programming Live with Larry · 9:55 · 597 views
Vol156 - Leetcode - Problem 748 - Shortest completing word - Golang - Phỏng vấn - Thuật toánYuh lập trình viên · 18:40 · 208 views
Leetcode Python - Shortest Completing WordShipItParrot · 31:30 · 116 views
The problem
Given a string licensePlate and an array of strings words, find the shortest completing word in words.
A completing word is a word that contains all the letters in licensePlate. Ignore numbers and spaces in licensePlate, and treat letters as case insensitive. If a letter appears more than once in licensePlate, then it must appear in the word the same number of times or more.
For example, if licensePlate = "aBc 12c", then it contains letters 'a', 'b' (ignoring case), and 'c' twice. Possible completing words are "abccdef", "caaacab", and "cbca".
Return the shortest completing word in words. It is guaranteed an answer exists. If there are multiple shortest completing words, return the first one that occurs in words.
Example 1:
Input: licensePlate = "1s3 PSt", words = ["step","steps","stripe","stepple"] Output: "steps" Explanation: licensePlate contains letters 's', 'p', 's' (ignoring case), and 't'. "step" contains 't' and 'p', but only contains 1 's'. "steps" contains 't', 'p', and both 's' characters. "stripe" is missing an 's'. "stepple" is missing an 's'. Since "steps" is the only word containing all the letters, that is the answer.
Example 2:
Input: licensePlate = "1s3 456", words = ["looks","pest","stew","show"] Output: "pest" Explanation: licensePlate only contains the letter 's'. All the words contain 's', but among these "pest", "stew", and "show" are shortest. The answer is "pest" because it is the word that appears earliest of the 3.
Constraints:
1 <= licensePlate.length <= 7licensePlatecontains digits, letters (uppercase or lowercase), or space' '.1 <= words.length <= 10001 <= words[i].length <= 15words[i]consists of lower case English letters.
Approach overview
Problem Overview: You receive a licensePlate string containing letters, digits, and spaces, plus a list of candidate words. The goal is to return the shortest word that contains every letter from the license plate with at least the same frequency, ignoring case and non‑letter characters.
Approach 1: Counting Letters and Validating Words (O(n * m) time, O(1) space)
This approach treats the problem as a frequency matching task. First iterate through licensePlate and build a fixed-size frequency array of 26 characters for required letters. Ignore digits and spaces, and convert everything to lowercase. Then iterate through each word in the list and compute its own frequency count. Compare the word's counts with the required counts. If the word satisfies every letter requirement, it is a valid completing word. Track the shortest valid candidate while scanning. The constant-sized frequency array keeps space complexity at O(1), and the algorithm performs straightforward scans over each word. This solution heavily uses ideas from hash table style frequency counting and basic string processing.
Approach 2: Using Regular Expressions and Sets (O(n * m) time, O(k) space)
This variant builds validation logic using pattern matching instead of explicit frequency arrays. Extract all letters from licensePlate, normalize them to lowercase, and derive constraints that each candidate word must satisfy. Regular expressions with repeated lookaheads can enforce that required letters exist the needed number of times. Each word is then tested against this compiled pattern. A set can help track unique letters when constructing constraints, while repeated characters must still be encoded in the regex pattern. While the asymptotic time complexity remains O(n * m), regex engines introduce additional constant overhead compared to simple counting. This technique may appeal when your environment already relies heavily on pattern matching logic or when you want a compact validation step.
Recommended for interviews: The counting approach is what interviewers typically expect. It demonstrates understanding of frequency counting, efficient iteration, and constant‑space optimization using a fixed 26‑character array. The regex approach works but hides the core algorithmic idea behind pattern matching. Showing the counting solution first proves you can translate the problem into a clear constraint check using basic array operations.
Approach 1: Counting Letters and Validating Words
In this approach, we focus on counting the frequency of each letter in the licensePlate and then check for each word in the words list whether it completes these letters with equal or more frequency.
Steps:
- Normalize the licensePlate string to lowercase and filter out non-letter characters.
- Use a frequency counter to count occurrences of each letter in the licensePlate.
- For each word in the words list, create a frequency counter and verify if it meets or exceeds the frequency for all letters from the licensePlate.
- Track the shortest word that satisfies these conditions.
from collections import Counter
def shortestCompletingWord(licensePlate, words):
# Extract only the letters from the licensePlate and convert to lowercase
filtered_letters = ''.join([char.lower() for char in licensePlate if char.isalpha()])
# Count the frequency of the required letters
plate_count = Counter(filtered_letters)
result = None
for word in words:
word_count = Counter(word)
# Check if word_count has all required letters in necessary frequency
if all(word_count[char] >= plate_count[char] for char in plate_count):
if result is None or len(word) < len(result):
result = word
return resultfunction shortestCompletingWord(licensePlate, words) {
const getCharCount = (str) => {
const count = {};
for (let char of str.toLowerCase()) {
if (char >= 'a' && char <= 'z') {
count[char] = (count[char] || 0) + 1;
}
}
return count;
};
const plateCount = getCharCount(licensePlate);
let result = null;
for (let word of words) {
const wordCount = getCharCount(word);
let isCompleting = true;
for (const char in plateCount) {
if ((wordCount[char] || 0) < plateCount[char]) {
isCompleting = false;
break;
}
}
if (isCompleting && (!result || word.length < result.length)) {
result = word;
}
}
return result;
}The solution uses Python's collections.Counter to count the frequency of the alphabetic characters in the licensePlate string and the words list. For each word, it checks if every character in the licensePlate exists in the word with at least the same frequency.
Time Complexity: O(n * m), where n is the number of words and m is the average length of the words.
Space Complexity: O(k), where k is the number of unique alphabetic characters in the licensePlate.
Approach 2: Using Regular Expressions and Sets
This approach involves using regular expressions to extract letters from licensePlate and using sets to check the presence of required characters in words.
Steps:
- Use a regular expression to extract all alphabetic characters from licensePlate and convert them to lowercase.
- Use sets to store these required characters.
- For each word, verify that it contains each of these characters in the required frequencies.
- Track the shortest word that satisfies these conditions.
import java.util.*;
public class Solution {
public String shortestCompletingWord(String licensePlate, String[] words) {
// Extract only letters and convert to lowercase
String filtered = licensePlate.toLowerCase().replaceAll("[^a-z]", "");
int[] plateCount = new int[26];
// Count occurrences of each character in the licensePlate
for (char c : filtered.toCharArray()) {
plateCount[c - 'a']++;
}
String result = null;
for (String word : words) {
int[] wordCount = new int[26];
for (char c : word.toCharArray()) {
wordCount[c - 'a']++;
}
boolean isCompleting = true;
for (int i = 0; i < 26; i++) {
if (plateCount[i] > 0 && wordCount[i] < plateCount[i]) {
isCompleting = false;
break;
}
}
if (isCompleting && (result == null || word.length() < result.length())) {
result = word;
}
}
return result;
}
}using System;
using System.Linq;
public class Solution {
public string ShortestCompletingWord(string licensePlate, string[] words) {
var required = licensePlate.ToLower().Where(char.IsLetter).GroupBy(x => x)
.ToDictionary(g => g.Key, g => g.Count());
string shortestWord = null;
foreach (var word in words) {
var wordCount = word.GroupBy(x => x).ToDictionary(g => g.Key, g => g.Count());
bool isCompleting = required.All(kvp => wordCount.ContainsKey(kvp.Key) && wordCount[kvp.Key] >= kvp.Value);
if (isCompleting && (shortestWord == null || word.Length < shortestWord.Length)) {
shortestWord = word;
}
}
return shortestWord;
}
}The Java solution utilizes arrays to count character frequencies. It processes the licensePlate to filter out alphabetic characters, and for each word, checks if it can complete the character counts from the licensePlate.
Time Complexity: O(n * m), where n is the number of words and m is the average length of the words.
Space Complexity: O(1), apart from input storage, we only use fixed size frequency arrays.
Approach 3: Counting
First, we use a hash table or an array cnt of length 26 to count the frequency of each letter in the string licensePlate. Note that we convert all letters to lowercase for counting.
Then, we traverse each word w in the array words. If the length of the word w is longer than the length of the answer ans, we directly skip this word. Otherwise, we use another hash table or an array t of length 26 to count the frequency of each letter in the word w. If for any letter, the frequency of this letter in t is less than the frequency of this letter in cnt, we can also directly skip this word. Otherwise, we have found a word that meets the conditions, and we update the answer ans to the current word w.
The time complexity is O(n times |\Sigma|), and the space complexity is O(|\Sigma|). Here, n is the length of the array words, and \Sigma is the character set. In this case, the character set is all lowercase letters, so |\Sigma| = 26.
class Solution {
public:
string shortestCompletingWord(string licensePlate, vector<string>& words) {
int cnt[26]{};
for (char& c : licensePlate) {
if (isalpha(c)) {
++cnt[tolower(c) - 'a'];
}
}
string ans;
for (auto& w : words) {
if (ans.size() && ans.size() <= w.size()) {
continue;
}
int t[26]{};
for (char& c : w) {
++t[c - 'a'];
}
bool ok = true;
for (int i = 0; i < 26; ++i) {
if (cnt[i] > t[i]) {
ok = false;
break;
}
}
if (ok) {
ans = w;
}
}
return ans;
}
};function shortestCompletingWord(licensePlate: string, words: string[]): string {
const cnt: number[] = Array(26).fill(0);
for (const c of licensePlate) {
const i = c.toLowerCase().charCodeAt(0) - 97;
if (0 <= i && i < 26) {
++cnt[i];
}
}
let ans = '';
for (const w of words) {
if (ans.length && ans.length <= w.length) {
continue;
}
const t = Array(26).fill(0);
for (const c of w) {
++t[c.charCodeAt(0) - 97];
}
let ok = true;
for (let i = 0; i < 26; ++i) {
if (t[i] < cnt[i]) {
ok = false;
break;
}
}
if (ok) {
ans = w;
}
}
return ans;
}func shortestCompletingWord(licensePlate string, words []string) (ans string) {
cnt := [26]int{}
for _, c := range licensePlate {
if unicode.IsLetter(c) {
cnt[unicode.ToLower(c)-'a']++
}
}
for _, w := range words {
if len(ans) > 0 && len(ans) <= len(w) {
continue
}
t := [26]int{}
for _, c := range w {
t[c-'a']++
}
ok := true
for i, v := range cnt {
if t[i] < v {
ok = false
break
}
}
if ok {
ans = w
}
}
return
}impl Solution {
pub fn shortest_completing_word(license_plate: String, words: Vec<String>) -> String {
let mut cnt = vec![0; 26];
for c in license_plate.chars() {
if c.is_ascii_alphabetic() {
cnt[((c.to_ascii_lowercase() as u8) - b'a') as usize] += 1;
}
}
let mut ans = String::new();
for w in words {
if !ans.is_empty() && w.len() >= ans.len() {
continue;
}
let mut t = vec![0; 26];
for c in w.chars() {
t[((c as u8) - b'a') as usize] += 1;
}
let mut ok = true;
for i in 0..26 {
if t[i] < cnt[i] {
ok = false;
break;
}
}
if ok {
ans = w;
}
}
ans
}
}Complexity comparison
| Approach | Complexity |
|---|---|
| Counting Letters and Validating Words | Time Complexity: O(n * m), where n is the number of words and m is the average length of the words. |
| Using Regular Expressions and Sets | Time Complexity: O(n * m), where n is the number of words and m is the average length of the words. |
| Counting | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Counting Letters and Validating Words | O(n * m) | O(1) | Best general solution. Fast, simple, and interview friendly. |
| Regular Expressions and Sets | O(n * m) | O(k) | Useful when pattern matching tools are preferred or already used in the codebase. |
Frequently asked questions
Is Shortest Completing Word easy or hard?
Shortest Completing Word is categorized as an Easy problem on LeetCode. The challenge mainly involves careful string filtering and frequency comparison rather than complex algorithms. Understanding character counting patterns is enough to solve it efficiently.
How to solve Shortest Completing Word in O(n)?
A strict O(n) solution is not possible because each candidate word must be inspected character by character. The optimal practical solution is O(n * m) using frequency counting. Precompute the required letter counts from the license plate and validate each word against those counts.
What is the best approach for Shortest Completing Word?
The most reliable approach uses letter frequency counting. Build a 26-length array from the license plate to record required character counts, then check each word against this requirement. The first shortest valid word that satisfies all counts is returned. This runs in O(n * m) time and O(1) extra space.
Is Shortest Completing Word asked at Google/Amazon/Meta?
Shortest Completing Word appears in interview preparation sets and online assessments that test string processing and frequency counting. Variations of this pattern—checking if one string satisfies the character requirements of another—are common in interviews at companies like Amazon and Google.
What data structure is used in Shortest Completing Word?
The core data structure is a fixed-size array (or hash table) representing character frequencies. This allows constant-time updates and comparisons for each letter. Arrays of size 26 are typically used since the problem only deals with lowercase English letters.
What is the time complexity of Shortest Completing Word?
The typical solution runs in O(n * m) time, where n is the number of words and m is the average length of each word. Each word must be scanned to compute or compare character frequencies. Space complexity is O(1) when using a fixed array of 26 letters.
Shortest Completing Word Python or Java solution approach?
Python and Java implementations usually follow the same strategy: compute a frequency array from the license plate, then compare it with the frequency of each word. Python often uses lists or collections.Counter, while Java commonly uses int[26] arrays for efficiency.
