def shortest_unique_prefix(words):
# Write your solution here
pass
class Solution {
public String[] shortestUniquePrefix(String[] words) {
// Write your solution here
return new String[words.length];
}
}
#include <vector>
#include <string>
using namespace std;
vector<string> shortestUniquePrefix(vector<string> &words) {
// Write your solution here
return vector<string>(words.size());
}
function shortestUniquePrefix(words) {
// Write your solution here
}
Coming soon
0/10
Common Bugs to Avoid
Wrong: ["z", "d", "du", "dov"]Stopping prefix too early for 'dog' by not checking full word uniqueness.✅ Continue prefix extension until frequency count at trie node is 1 or full word length is reached.
Wrong: ["app", "ap", "apr", "b"]Incorrect prefix for 'ape' by stopping prefix too early ignoring shared prefixes.✅ Use trie node frequency counts to ensure prefix is unique; extend prefix until frequency is 1.
Wrong: ["test", "test", "testi"]Failing to extend prefix for 'testing' when 'test' is prefix of it.✅ Extend prefix for longer word beyond shorter word length until uniqueness is found.
Wrong: ["a", "a", "a"]All words identical but returning same prefix for all instead of full words.✅ Return entire word as prefix when all words are identical.
Wrong: nullBrute force or sorting approach causes TLE on large inputs.✅ Implement trie-based O(n*m) solution to handle large input efficiently.
✓
Test Cases
Focus on handling empty inputs and single-element lists correctly before tackling edge cases.
Ensure your prefix length logic correctly handles words that are prefixes of others and shared prefixes.
Optimize your solution to use a trie with frequency counts to handle large inputs efficiently.
t1_01basic
Input["zebra","dog","duck","dove"]
Expected["z","dog","du","dov"]
⏱ Performance - must finish in 2000ms
For 'zebra', 'z' is unique. For 'dog', 'dog' itself is unique since 'd' and 'do' are shared with 'duck' and 'dove'. For 'duck', 'du' is unique. For 'dove', 'dov' is unique.
💡 Consider building a trie to count prefixes shared by multiple words.
💡 Use frequency counts at each trie node to identify uniqueness.
💡 The shortest unique prefix ends where the frequency count is 1.
Why it failed: Incorrect prefixes indicate failure to track prefix uniqueness correctly. Fix by counting frequency of prefixes in trie nodes and stopping prefix at first node with frequency 1.
✓ Correctly identifies shortest unique prefixes using prefix frequency counts.
t1_02basic
Input["apple","ape","april","bat"]
Expected["app","ape","apr","b"]
⏱ Performance - must finish in 2000ms
For 'apple', 'app' is unique; 'ape' is unique itself; 'april' needs 'apr'; 'bat' is unique with 'b'.
💡 Words sharing initial letters require longer prefixes to be unique.
💡 Check prefix frequency counts in trie nodes to determine uniqueness.
💡 Stop prefix at first node with frequency 1 to get shortest unique prefix.
Why it failed: Failing to extend prefix enough for words sharing initial letters causes wrong output. Fix by continuing prefix until frequency count is 1 in trie.
✓ Correctly extends prefixes to ensure uniqueness among similar words.
t2_01edge
Input[]
Expected[]
⏱ Performance - must finish in 2000ms
Empty input list returns empty output list.
💡 Check for empty input before processing.
💡 Return empty list immediately if no words.
💡 Avoid building trie or loops when input is empty.
Why it failed: Code crashes or returns non-empty output on empty input. Fix by adding early return for empty input list.
✓ Handles empty input gracefully by returning empty list.
t2_02edge
Input["a"]
Expected["a"]
⏱ Performance - must finish in 2000ms
Single word with one character returns the character itself as unique prefix.
💡 Single word means prefix is the word itself.
💡 Check prefix frequency counts; single word frequency is 1 at root.
💡 Return the entire word if no shorter unique prefix exists.
Why it failed: Fails to handle single word input or returns empty prefix. Fix by returning the word itself when only one word is present.
✓ Correctly returns the entire word as unique prefix for single word input.
t2_03edge
Input["test","testing"]
Expected["test","testi"]
⏱ Performance - must finish in 2000ms
'test' is prefix of 'testing'; 'test' itself is unique prefix for first word; 'testing' needs longer prefix 'testi'.
💡 When one word is prefix of another, longer word needs longer prefix.
💡 Check prefix frequency counts carefully for words that are prefixes of others.
💡 Stop prefix at first node with frequency 1, which may be beyond the shorter word length.
Why it failed: Fails to extend prefix for longer word when shorter word is prefix. Fix by continuing prefix until frequency count is 1 even if prefix length exceeds shorter word length.
✓ Correctly handles prefix relationships by extending longer word's prefix.
t2_04edge
Input["same","same","same"]
Expected["same","same","same"]
⏱ Performance - must finish in 2000ms
All words are identical; shortest unique prefix is the entire word for each.
💡 All identical words mean no shorter unique prefix exists.
💡 Frequency counts at each node equal number of identical words.
💡 Return full word as prefix for all identical words.
Why it failed: Returning shorter prefixes for identical words causes non-unique prefixes. Fix by returning full word when all words are identical.
✓ Correctly returns full words as prefixes for identical inputs.
t3_01corner
Input["abc","abd","abe"]
Expected["abc","abd","abe"]
⏱ Performance - must finish in 2000ms
All words share prefix 'ab' but differ at third character, so full words are shortest unique prefixes.
💡 Check if prefix length must be full word length when all prefixes are shared.
💡 Trie node frequency counts remain >1 until last character.
💡 Stop prefix at first node with frequency 1, which may be last character.
Why it failed: Stopping prefix too early causes non-unique prefixes. Fix by continuing prefix until frequency count is 1, even if that means full word.
✓ Correctly returns full words when prefixes are shared up to last character.
t3_02corner
Input["a","aa","aaa"]
Expected["a","aa","aaa"]
⏱ Performance - must finish in 2000ms
Words are prefixes of each other; each longer word needs longer prefix to be unique.
💡 Check prefix length carefully when words are prefixes of each other.
💡 Trie frequency counts decrease only after extending prefix beyond shorter words.
💡 Ensure prefix length can be equal to word length.
Why it failed: Using greedy approach stopping at first differing character fails here. Fix by checking frequency counts at each node and extending prefix fully if needed.
✓ Handles prefix chains correctly by extending prefixes to full word length if necessary.
t3_03corner
Input["car","cat","dog","dot"]
Expected["car","cat","dog","dot"]
⏱ Performance - must finish in 2000ms
Words share first two letters but differ at third; shortest unique prefix is full word.
💡 Check that prefix length extends to first differing character.
💡 Trie frequency counts remain >1 until last character for these words.
💡 Stop prefix at first node with frequency 1, which is last character here.
Why it failed: Stopping prefix too early causes non-unique prefixes. Fix by continuing prefix until frequency count is 1, even if that means full word.
✓ Correctly returns full words when prefixes are shared up to last character.
t4_01performance
Input{"_description":"n=100000 at constraint boundary - executor generates this"}
Expectednull
⏱ Performance - must finish in 2000ms
Input size n=100000 with max word length 100 requires O(n*m) solution to complete within 2 seconds.
💡 Brute force O(n^2*m) will time out; use trie with frequency counts.
💡 Trie approach runs in O(n*m) time, suitable for large inputs.
💡 Avoid pairwise prefix comparisons; build trie once and query.
Why it failed: Brute force or sorting-based solutions time out on large inputs. Fix by implementing trie-based O(n*m) solution.
✓ Efficient trie-based solution runs within time limits.
Practice
(1/5)
1. The following code attempts to find index pairs of substrings matching words using a trie + DFS approach. Identify the line containing the subtle bug that causes incorrect or incomplete results.
medium
A. Line: return res # Missing sorting before return
B. Line: if i == n: return
C. Line: for i in range(n): dfs(root, i, i)
D. Line: if node.word_end: res.append([start, i-1])
Solution
Step 1: Identify expected output order
The problem requires the output list of index pairs to be sorted. The code returns res without sorting.
Step 2: Understand impact of missing sort
Without sorting, the output order may differ from expected, causing wrong answer in tests even if all pairs are found.
Final Answer:
Option A -> Option A
Quick Check:
Adding res.sort() before return fixes the bug [OK]
Hint: Output must be sorted before returning [OK]
Common Mistakes:
Forgetting to sort results before returning
2. The following code attempts to answer maximum XOR queries with constraints using a bit trie. Which line contains a subtle bug that can cause incorrect results or runtime errors when no nums ≤ m are available?
medium
A. Line: node = node.children[bit]
B. Line: if not node.children[bit]: node.children[bit] = TrieNode()
C. Line: node = self.root
D. Line: if node.children[toggled_bit]:
Solution
Step 1: Identify empty trie scenario
If no nums ≤ m, trie is empty; node.children[bit] can be None.
Step 2: Check max_xor traversal
Line assigning node = node.children[bit] assumes child exists, causing runtime error or wrong result.
Final Answer:
Option A -> Option A
Quick Check:
Must handle empty child case to avoid errors [OK]
Hint: Check for None before descending trie [OK]
Common Mistakes:
Ignoring empty trie case
Assuming children always exist
Not returning -1 when no valid nums
3. Suppose the problem is modified so that pairs can be counted multiple times if elements are reused (i.e., pairs (i, j) with i and j possibly equal). Which modification to the bitwise trie approach correctly handles this scenario?
hard
A. Modify the query function to include the current number in the trie before querying to count pairs with itself.
B. No change needed; the existing approach already counts pairs with reuse.
C. Insert all numbers into the trie first, then for each number query the trie for counts less than limit, allowing reuse.
D. Use a frequency map instead of a trie since reuse breaks trie assumptions.
Solution
Step 1: Understand reuse means pairs can include the same element twice
Counting pairs with i == j means the current number must be considered in queries.
Step 2: Modify insertion and query order
Insert the current number into the trie before querying so it can pair with itself and others, enabling reuse counting.
Final Answer:
Option A -> Option A
Quick Check:
Inserting before querying allows counting pairs including the current element [OK]
Hint: Insert before query to count pairs with reuse [OK]
Common Mistakes:
Assuming no change needed
Inserting after query (misses self pairs)
Switching to frequency map unnecessarily
4. Suppose the problem is modified so that words can be reused multiple times in pairs (i.e., pairs like (i, i) are allowed). Which modification to the Trie + DFS approach correctly handles this variant without producing duplicates or missing pairs?
hard
A. Modify add_word to store all occurrences of the same word and allow same index pairs
B. Keep the check that skips pairs with equal indices but add a separate pass to handle reuse pairs
C. Allow same index pairs by removing index checks but filter duplicates after collecting all pairs
D. Remove the check that skips pairs where indices are equal in search and palindrome_suffixes loops
Solution
Step 1: Understand reuse allowance
Allowing pairs (i, i) means removing index inequality checks but risks duplicates.
Step 2: Modify search and add_word accordingly
Removing index checks alone causes duplicates; filtering duplicates after collection ensures correctness.
Step 3: Why other options fail
Removing checks without filtering causes duplicates; separate pass is inefficient; storing all occurrences is unnecessary.
Final Answer:
Option C -> Option C
Quick Check:
Removing index checks + duplicate filtering handles reuse correctly [OK]
Hint: Allow reuse by removing index checks + filtering duplicates [OK]
Common Mistakes:
Removing index checks without filtering
Adding complex separate passes
Confusing occurrences with indices
5. Suppose the problem is modified so that each letter cell on the board can be reused multiple times within the same word (i.e., no visited marking needed). Which modification to the Trie + DFS algorithm correctly handles this variant without causing infinite loops or incorrect results?
hard
A. Remove visited marking and add a depth limit equal to the maximum word length to prevent infinite recursion.
B. Use BFS instead of DFS to avoid revisiting cells infinitely.
C. Keep visited marking but reset it after each DFS call to allow reuse.
D. Remove visited marking and keep DFS as is; no other changes needed.
Solution
Step 1: Understand reuse allows cycles
Without visited marking, DFS can revisit the same cell infinitely, causing infinite recursion.
Step 2: Add depth limit to DFS
Limiting recursion depth to the maximum word length prevents infinite loops while allowing reuse of cells.
Final Answer:
Option A -> Option A
Quick Check:
Depth limit bounds recursion, enabling correct search with reuse [OK]
Hint: Depth limit prevents infinite recursion when reuse allowed [OK]
Common Mistakes:
Removing visited marking without depth limit causes infinite loops
Keeping visited marking contradicts reuse
Switching to BFS doesn't solve infinite recursion
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.