Сложность: hard
Дано массив уникальных строк words, верните минимально возможные сокращения для каждого слова.
Правила сокращения строки следующие:
Первоначальное сокращение для каждого слова: первый символ, затем количество символов между первым и последним символом, затем последний символ.
Если более одного слова имеют одинаковое сокращение, выполните следующее:
Увеличьте префикс (символы в первой части) каждого из их сокращений на 1.
Например, начнем с слов ["abcdef", "abndef"], оба изначально сокращены как "a4f". Последовательность операций будет следующей: ["a4f", "a4f"] -> ["ab3f", "ab3f"] -> ["abc2f", "abn2f"].
Эта операция повторяется до тех пор, пока каждое сокращение не станет уникальным.
В конце, если сокращение не сделало слово короче, оставьте его в исходном виде.
Пример:
Input: words = ["like","god","internal","me","internet","interval","intension","face","intrusion"]
Output: ["l2e","god","internal","me","i6t","interval","inte4n","f2e","intr4n"]
👨💻 Алгоритм:
1⃣ Инициализация и создание начальных сокращений:
Создайте массив для хранения сокращений и массив для отслеживания длины префикса каждого слова.
Для каждого слова создайте начальное сокращение с использованием первого символа, количества символов между первым и последним символом и последнего символа.
2⃣ Обработка коллизий:
Для каждого слова проверьте, не совпадает ли его сокращение с уже существующими сокращениями.
Если сокращение не уникально, увеличьте длину префикса и повторите проверку.
3⃣ Возврат результата:
Верните окончательные сокращения для каждого слова, убедившись, что они минимально возможны и уникальны.
😎 Решение:
class Solution {
func wordsAbbreviation(_ words: [String]) -> [String] {
let n = words.count
var ans = Array(repeating: "", count: n)
var prefix = Array(repeating: 0, count: n)
for i in 0..<n {
ans[i] = abbrev(words[i], 0)
}
for i in 0..<n {
while true {
var dupes = Set<Int>()
for j in (i+1)..<n {
if ans[i] == ans[j] {
dupes.insert(j)
}
}
if dupes.isEmpty { break }
dupes.insert(i)
for k in dupes {
ans[k] = abbrev(words[k], prefix[k] + 1)
prefix[k] += 1
}
}
}
return ans
}
private func abbrev(_ word: String, _ i: Int) -> String {
let n = word.count
if n - i <= 3 { return word }
let start = word.prefix(i + 1)
let end = word.suffix(1)
return "\(start)\(n - i - 2)\(end)"
}
}Ставь 👍 и забирай 📚 Базу знаний