Skip to content

Commit 48637c4

Browse files
committed
Add solution #527
1 parent 64c6d84 commit 48637c4

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@
513513
524|[Longest Word in Dictionary through Deleting](./solutions/0524-longest-word-in-dictionary-through-deleting.js)|Medium|
514514
525|[Contiguous Array](./solutions/0525-contiguous-array.js)|Medium|
515515
526|[Beautiful Arrangement](./solutions/0526-beautiful-arrangement.js)|Medium|
516+
527|[Word Abbreviation](./solutions/0527-word-abbreviation.js)|Hard|
516517
528|[Random Pick with Weight](./solutions/0528-random-pick-with-weight.js)|Medium|
517518
529|[Minesweeper](./solutions/0529-minesweeper.js)|Medium|
518519
530|[Minimum Absolute Difference in BST](./solutions/0530-minimum-absolute-difference-in-bst.js)|Easy|

solutions/0527-word-abbreviation.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* 527. Word Abbreviation
3+
* https://leetcode.com/problems/word-abbreviation/
4+
* Difficulty: Hard
5+
*
6+
* Given an array of distinct strings words, return the minimal possible abbreviations for
7+
* every word.
8+
*
9+
* The following are the rules for a string abbreviation:
10+
* 1. The initial abbreviation for each word is: the first character, then the number of
11+
* characters in between, followed by the last character.
12+
* 2. If more than one word shares the same abbreviation, then perform the following operation:
13+
* - Increase the prefix (characters in the first part) of each of their abbreviations by 1.
14+
* - For example, say you start with the words ["abcdef","abndef"] both initially abbreviated
15+
* as "a4f". Then, a sequence of operations would be
16+
* ["a4f","a4f"] -> ["ab3f","ab3f"] -> ["abc2f","abn2f"].
17+
* - This operation is repeated until every abbreviation is unique.
18+
* 3. At the end, if an abbreviation did not make a word shorter, then keep it as the original word.
19+
*/
20+
21+
/**
22+
* @param {string[]} words
23+
* @return {string[]}
24+
*/
25+
var wordsAbbreviation = function(words) {
26+
const n = words.length;
27+
const result = new Array(n).fill('');
28+
const groups = new Map();
29+
30+
function getAbbreviation(word, prefixLen) {
31+
const len = word.length;
32+
if (len <= prefixLen + 2) return word;
33+
return word.slice(0, prefixLen) + (len - prefixLen - 1) + word[len - 1];
34+
}
35+
36+
for (let i = 0; i < n; i++) {
37+
const word = words[i];
38+
const prefixLen = 1;
39+
const abbr = getAbbreviation(word, prefixLen);
40+
41+
if (!groups.has(abbr)) {
42+
groups.set(abbr, []);
43+
}
44+
groups.get(abbr).push([i, prefixLen]);
45+
}
46+
47+
while (true) {
48+
let resolved = true;
49+
const newGroups = new Map();
50+
51+
for (const [abbr, indices] of groups) {
52+
if (indices.length === 1) {
53+
const [index, prefixLen] = indices[0];
54+
const word = words[index];
55+
const finalAbbr = getAbbreviation(word, prefixLen);
56+
result[index] = finalAbbr.length < word.length ? finalAbbr : word;
57+
continue;
58+
}
59+
60+
resolved = false;
61+
for (const [index, prefixLen] of indices) {
62+
const word = words[index];
63+
const newAbbr = getAbbreviation(word, prefixLen + 1);
64+
65+
if (!newGroups.has(newAbbr)) {
66+
newGroups.set(newAbbr, []);
67+
}
68+
newGroups.get(newAbbr).push([index, prefixLen + 1]);
69+
}
70+
}
71+
72+
if (resolved) break;
73+
groups.clear();
74+
for (const [abbr, indices] of newGroups) {
75+
groups.set(abbr, indices);
76+
}
77+
}
78+
79+
return result;
80+
};

0 commit comments

Comments
 (0)