Given an array of distinct strings words, return the minimal possibleabbreviations for every word.
The following are the rules for a string abbreviation:
The initial abbreviation for each word is: the first character, then the number of characters in between, followed by the last character.
If more than one word shares the same abbreviation, then perform the following operation:
Increase the prefix (characters in the first part) of each of their abbreviations by 1.
For example, say you start with the words ["abcdef","abndef"] both initially abbreviated as "a4f". Then, a sequence of operations would be ["a4f","a4f"] -> ["ab3f","ab3f"] -> ["abc2f","abn2f"].
This operation is repeated until every abbreviation is unique.
At the end, if an abbreviation did not make a word shorter, then keep it as the original word.
Input: words =["like","god","internal","me","internet","interval","intension","face","intrusion"]Output: ["l2e","god","internal","me","i6t","interval","inte4n","f2e","intr4n"]
We want the shortest unique abbreviation for each word. Start with the minimal abbreviation (first letter + count + last letter). If abbreviations collide, increase the prefix length for those words and repeat until all are unique. If the abbreviation is not shorter than the word, use the word itself.
classSolution {
funwordsAbbreviation(words: List<String>): List<String> {
val n = words.size
val pre = IntArray(n) { 1 }
val ans = Array(n) { "" }
funabbr(w: String, p: Int): String {
if (w.length - p <=2) return w
return w.substring(0, p) + (w.length - p - 1).toString() + w.last()
}
while (true) {
val groups = mutableMapOf<String, MutableList<Int>>()
for (i in0 until n) {
ans[i] = abbr(words[i], pre[i])
groups.getOrPut(ans[i]) { mutableListOf() }.add(i)
}
var unique = truefor (v in groups.values) {
if (v.size > 1) {
unique = falsefor (idx in v) pre[idx]++ }
}
if (unique) break }
for (i in0 until n) {
if (ans[i].length >= words[i].length) ans[i] = words[i]
}
return ans.toList()
}
}
from typing import List
classSolution:
defwordsAbbreviation(self, words: List[str]) -> List[str]:
n = len(words)
pre = [1] * n
ans = [''] * n
defabbr(w: str, p: int) -> str:
if len(w) - p <=2:
return w
return w[:p] + str(len(w) - p -1) + w[-1]
whileTrue:
groups = {}
for i in range(n):
ans[i] = abbr(words[i], pre[i])
groups.setdefault(ans[i], []).append(i)
unique =Truefor v in groups.values():
if len(v) >1:
unique =Falsefor idx in v:
pre[idx] +=1if unique:
breakfor i in range(n):
if len(ans[i]) >= len(words[i]):
ans[i] = words[i]
return ans
⏰ Time complexity: O(n * L^2) — For n words of length L, in the worst case, we may need to increase the prefix for each word up to L, and each time we group all n words.
🧺 Space complexity: O(n * L) — For storing abbreviations and prefix lengths.