PracHub
QuestionsCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates a candidate's ability to design a string-processing algorithm involving iterative refinement and conflict resolution among grouped elements. It tests string manipulation, hashing for grouping, and careful edge-case handling under length constraints, a common way to assess practical coding proficiency in algorithm interviews.

  • medium
  • Apple
  • Coding & Algorithms
  • Software Engineer

Minimal Unique Word Abbreviations

Company: Apple

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Onsite

# Minimal Unique Word Abbreviations You are given an array `words` of `n` **distinct** strings. Produce a **minimal abbreviation** for every word according to the rules below, and return the abbreviations in the **same order** as the input. ## How an abbreviation is formed An abbreviation of a word uses a **prefix** of the first `k` characters, followed by the **count** of the characters between that prefix and the last character, followed by the **last** character. For a prefix length `k` (with `1 <= k <= length - 2`): ``` abbr(word, k) = word[0 .. k-1] + (length - k - 1) + word[length - 1] ``` With the smallest prefix `k = 1`, this is: `first character` + `(length - 2)` + `last character`. For example: - `"apple"` -> `"a3e"` (`a`, then 3 middle characters `ppl`, then `e`) - `"internationalization"` -> `"i18n"` ## Rules for choosing each word's abbreviation 1. Start every word at `k = 1` (the shortest abbreviation). 2. If an abbreviation is **shared by two or more words**, those conflicting words must use a **longer prefix**: increase `k` for the conflicting words and recompute, repeating until each word's abbreviation is **unique** among all words. 3. If at any point a word's abbreviation is **not shorter** than the original word (its length is `>=` the word's length), use the **original word** itself instead of the abbreviation. ## Examples - Input: `["dog", "deer", "deal"]` Output: `["dog", "d2r", "d2l"]` - `"dog"`: `"d1g"` has length 3, not shorter than `"dog"`, so keep `"dog"`. - `"deer"` -> `"d2r"`, `"deal"` -> `"d2l"`; these are already unique. - Input: `["abcdefz", "abxdefz"]` Output: `["abc3z", "abx3z"]` - At `k = 1` both become `"a5z"` (conflict); at `k = 2` both become `"ab4z"` (still conflict); at `k = 3` they become `"abc3z"` and `"abx3z"`, which are unique and shorter than the originals. ## Constraints - `1 <= n <= 400` - `2 <= words[i].length <= 400` - All strings in `words` are **distinct** and consist of lowercase English letters. ## Required Return an array of the minimal abbreviations, in the same order as `words`.

Quick Answer: This question evaluates a candidate's ability to design a string-processing algorithm involving iterative refinement and conflict resolution among grouped elements. It tests string manipulation, hashing for grouping, and careful edge-case handling under length constraints, a common way to assess practical coding proficiency in algorithm interviews.

You are given an array `words` of `n` distinct lowercase strings. Produce a minimal abbreviation for every word and return the abbreviations in the same order as the input. **Forming an abbreviation.** For a prefix length `k` (1-based), `abbr(word, k) = word[0..k-1] + (length - k - 1) + word[length-1]` — the first `k` characters, then the count of the middle characters, then the last character. With `k = 1`: first character + `(length - 2)` + last character. For example `"apple" -> "a3e"` and `"internationalization" -> "i18n"`. **Choosing each word's abbreviation.** 1. Start every word at `k = 1` (the shortest abbreviation). 2. If an abbreviation is shared by two or more words, increase `k` for the conflicting words and recompute, repeating until every word's abbreviation is unique among all words. 3. If at any point a word's abbreviation is not shorter than the original word (its length is `>=` the word's length), use the original word itself instead. Return the array of minimal abbreviations in the same order as `words`. **Examples** - `["dog", "deer", "deal"] -> ["dog", "d2r", "d2l"]` ("d1g" is not shorter than "dog", so "dog" is kept). - `["abcdefz", "abxdefz"] -> ["abc3z", "abx3z"]` (both collide at k=1 "a5z" and k=2 "ab4z", becoming unique at k=3). **Constraints** - `1 <= n <= 400` - `2 <= words[i].length <= 400` - All strings are distinct and consist of lowercase English letters.

Constraints

  • 1 <= n <= 400
  • 2 <= words[i].length <= 400
  • All strings in words are distinct and consist of lowercase English letters.
  • Abbreviations must be returned in the same order as the input.

Examples

Input: (["dog", "deer", "deal"],)

Expected Output: ["dog", "d2r", "d2l"]

Explanation: "d1g" is length 3, not shorter than "dog", so "dog" stays. "deer"->"d2r", "deal"->"d2l" are already unique.

Input: (["abcdefz", "abxdefz"],)

Expected Output: ["abc3z", "abx3z"]

Explanation: Both are "a5z" at k=1 and "ab4z" at k=2 (still colliding); at k=3 they become "abc3z" and "abx3z", unique and shorter.

Input: (["apple"],)

Expected Output: ["a3e"]

Explanation: Single word: "a" + 3 middle chars (ppl) + "e" = "a3e", which is unique and shorter.

Input: (["internationalization"],)

Expected Output: ["i18n"]

Explanation: Length 20: "i" + 18 middle characters + "n" = "i18n".

Input: (["it", "is"],)

Expected Output: ["it", "is"]

Explanation: Length-2 words: "i0t"/"i0s" would be length 3, not shorter, so the original words are kept and are already unique.

Input: (["abcz", "abdz", "axyz"],)

Expected Output: ["abcz", "abdz", "axyz"]

Explanation: All collide as "a2z" at k=1; at k=2 the candidates ("ab1z"/"ax1z") are length 4, not shorter than the length-4 words, so each falls back to its distinct original word.

Input: ([],)

Expected Output: []

Explanation: Empty input returns an empty list.

Hints

  1. Write a helper abbr(word, k) that builds first-k-chars + middle-count + last-char, and falls back to the original word whenever the candidate is not strictly shorter.
  2. Start every word at k = 1, then repeatedly find groups of words sharing the same current abbreviation and bump the prefix length k for every word in a colliding group.
  3. Because all input words are distinct and never contain digits, a full-word fallback can never collide with a digit-containing abbreviation, which guarantees the loop terminates.
Last updated: Jul 1, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,000+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Implement a FIFO Queue Using Two Stacks - Apple (medium)
  • Vertical Order Traversal of a Binary Tree - Apple (medium)
  • Convert a Roman Numeral to an Integer - Apple (medium)
  • Minimum Cells to Bridge a Magic Grid - Apple (hard)
  • Find Common Prefix Across Strings - Apple (easy)