Input: words = ["time", "me", "bell"]
Output: 10
Explanation: A valid encoding would be s = "time#bell#" and indices = [0, 2, 5].
words[0] = "time", the substring of s starting from indices[0] = 0 to the next '#' is underlined in "time#bell#"
words[1] = "me", the substring of s starting from indices[1] = 2 to the next '#' is underlined in "time#bell#"
words[2] = "bell", the substring of s starting from indices[2] = 5 to the next '#' is underlined in "time#bell#"
Example 2:
1
2
3
Input: words = ["t"]
Output: 2
Explanation: A valid encoding would be s = "t#" and indices = [0].
The problem has horrible description. Let’s get the deacription clear:
Given string list L1, construct a another string list L2, making every word in L1 be a suffix of a word in L2.
Return the minimum possible total length of words in L2
1
2
Input L1:[“time”,“me”,“bell”]L2: [“time”,“bell”]
Method 1 - Sort Strings in Desc Order by Length and Generate All Suffices and Check Uniqueness by Set#
publicintminimumLengthEncoding(String[] words) {
classNode {
String s;
int len;
Node(String s, int len) {
this.s= s;
this.len= len;
}
}
List<Node> list =new ArrayList<>();
for (String w : words) {
list.add(new Node(w, w.length()));
}
list.sort((o1, o2) -> Integer.compare(o2.len, o1.len));
Set<String> set =new HashSet<>();
int ans = 0;
for (Node node : list) {
String str = node.s;
if (!set.contains(str)) {
for (int i = 0, l = str.length(); i < l; i++) {
set.add(str.substring(i, l));
}
ans += (str.length() + 1);// +1 for `#` }
}
return ans;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution:
defminimumLengthEncoding(self, words: List[str]) -> int:
# Create a list of tuples (word, length) nodeList = sorted([(word, len(word)) for word in words], key=lambda x: -x[1])
seen = set()
ans =0for word, length in nodeList:
if word notin seen:
# Add all suffixes to the setfor i in range(length):
seen.add(word[i:])
# Increment the result length by word length + 1 (for '#') ans += length +1return ans
classSolution {
publicintminimumLengthEncoding(String[] words) {
Set<String> set =new HashSet<>(Arrays.asList(words));
for (String w: words) {
for (int i = 1; i<w.length(); ++i) {
set.remove(w.substring(i));
}
}
int ans = 0;
for (String w: set) {
ans += w.length() + 1;
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
classSolution:
defminimumLengthEncoding(self, words: List[str]) -> int:
word_set = set(words)
for word in words:
for i in range(1, len(word)):
word_set.discard(word[i:])
return sum(len(word) +1for word in word_set)
⏰ Time complexity: O(n * m^2), where n is the number of words and m is the maximum length of a word. This is because removing suffixes requires iterating over each word and its suffixes.
🧺 Space complexity: O(n * m), for storing the words and their suffixes in the set.
The concept of using a Trie is quite straightforward and becomes even clearer when dealing with suffixes. The approach involves inserting all reversed words into a Trie.
classSolution:
defminimumLengthEncoding(self, words: List[str]) -> int:
ifnot words:
return0 words.sort(key=len, reverse=True)
root = TrieNode()
ans =0for word in words:
if add(root, word):
ans += len(word) +1return ans
⏰ Time complexity: O(n * m) , where n is the number of words and m is the maximum length of a word. Sorting takes O(n log n), and inserting into the Trie takes O(n * m).
🧺 Space complexity: O(n * m) for storing all nodes in the Trie.