Description
You are given an array arr
of size n
consisting of non-empty strings.
Find a string array answer
of size n
such that:
-
answer[i]
is the shortestsubstring
of
arr[i]
that does not occur as a substring in any other string inarr
. If multiple such substrings exist,answer[i]
should be thelexicographically smallest
. And if no such substring exists,
answer[i]
should be an empty string.
Return the array answer
.
Example 1:
Input: arr = [“cab”,“ad”,“bad”,“c”] Output: [“ab”,"",“ba”,""] Explanation: We have the following:
- For the string “cab”, the shortest substring that does not occur in any other string is either “ca” or “ab”, we choose the lexicographically smaller substring, which is “ab”.
- For the string “ad”, there is no substring that does not occur in any other string.
- For the string “bad”, the shortest substring that does not occur in any other string is “ba”.
- For the string “c”, there is no substring that does not occur in any other string.
Example 2:
Input: arr = [“abc”,“bcd”,“abcd”] Output: ["","",“abcd”] Explanation: We have the following:
- For the string “abc”, there is no substring that does not occur in any other string.
- For the string “bcd”, there is no substring that does not occur in any other string.
- For the string “abcd”, the shortest substring that does not occur in any other string is “abcd”.
Constraints:
n == arr.length
2 <= n <= 100
1 <= arr[i].length <= 20
arr[i]
consists only of lowercase English letters.
Code
Time Complexity: , Space Complexity:
因為需要刪除,所以使用 count
來紀錄,而不是移除 pointer。
class Solution {
public:
struct Node {
Node* child[26];
int count;
Node(): count(0) {
for(int i = 0; i < 26; i++) {
child[i] = nullptr;
}
}
};
void add(Node* node, string& s) {
Node* ptr = node;
for(int i = 0; i < s.length(); i++) {
int c = s[i] - 'a';
if(ptr->child[c] == nullptr) {
ptr->child[c] = new Node();
}
ptr = ptr->child[c];
ptr->count++;
}
}
void remove(Node* node, string& s) {
Node* ptr = node;
for(int i = 0; i < s.length(); i++) {
int c = s[i] - 'a';
ptr = ptr->child[c];
ptr->count--;
}
}
bool exist(Node* node, string& s) {
Node* ptr = node;
for(int i = 0; i < s.length(); i++) {
int c = s[i] - 'a';
if(ptr->child[c] == nullptr)
return false;
ptr = ptr->child[c];
if(ptr->count == 0)
return false;
}
return true;
}
vector<string> shortestSubstrings(vector<string>& arr) {
Node* head = new Node();
for(auto& s: arr) {
for(int i = 0; i < s.length(); i++) {
for(int j = i; j < s.length(); j++) {
string sub = s.substr(i, j - i + 1);
add(head, sub);
}
}
}
vector<string> res;
for(auto& s: arr) {
// remove all s's substr
for(int i = 0; i < s.length(); i++) {
for(int j = i; j < s.length(); j++) {
string sub = s.substr(i, j - i + 1);
remove(head, sub);
}
}
// check all s's substr
string answer = s + s;
for(int i = 0; i < s.length(); i++) {
for(int j = i; j < s.length(); j++) {
string sub = s.substr(i, j - i + 1);
if(!exist(head, sub)) {
if(sub.length() < answer.length() || (sub.length() == answer.length() && sub < answer))
answer = sub;
}
}
}
res.push_back(answer.length() <= s.length() ? answer : "");
// add all s's substr back
for(int i = 0; i < s.length(); i++) {
for(int j = i; j < s.length(); j++) {
string sub = s.substr(i, j - i + 1);
add(head, sub);
}
}
}
return res;
}
};