1408-数组中的字符串匹配

Raphael Liu Lv10

给你一个字符串数组 words ,数组中的每个字符串都可以看作是一个单词。请你按 任意 顺序返回 words
中是其他单词的子字符串的所有单词。

如果你可以删除 words[j] 最左侧和/或最右侧的若干字符得到 words[i] ,那么字符串 words[i] 就是 words[j]
的一个子字符串。

示例 1:

**输入:** words = ["mass","as","hero","superhero"]
**输出:** ["as","hero"]
**解释:** "as" 是 "mass" 的子字符串,"hero" 是 "superhero" 的子字符串。
["hero","as"] 也是有效的答案。

示例 2:

**输入:** words = ["leetcode","et","code"]
**输出:** ["et","code"]
**解释:** "et" 和 "code" 都是 "leetcode" 的子字符串。

示例 3:

**输入:** words = ["blue","green","bu"]
**输出:** []

提示:

  • 1 <= words.length <= 100
  • 1 <= words[i].length <= 30
  • words[i] 仅包含小写英文字母。
  • 题目数据 保证 每个 words[i] 都是独一无二的。

方法一:暴力枚举

对于字符串数组中的某个字符串 words}[i],我们判断它是否是其他字符串的子字符串,只需要枚举 words}[j],其中 j \ne i,如果 words}[i] 是 words}[j] 的子字符串,那么将 words}[i] 加入结果中。

[sol1-Python3]
1
2
3
4
5
6
7
8
9
class Solution:
def stringMatching(self, words: List[str]) -> List[str]:
ans = []
for i, x in enumerate(words):
for j, y in enumerate(words):
if j != i and x in y:
ans.append(x)
break
return ans
[sol1-C++]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public:
vector<string> stringMatching(vector<string>& words) {
vector<string> ret;
for (int i = 0; i < words.size(); i++) {
for (int j = 0; j < words.size(); j++) {
if (i != j && words[j].find(words[i]) != string::npos) {
ret.push_back(words[i]);
break;
}
}
}
return ret;
}
};
[sol1-Java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public List<String> stringMatching(String[] words) {
List<String> ret = new ArrayList<String>();
for (int i = 0; i < words.length; i++) {
for (int j = 0; j < words.length; j++) {
if (i != j && words[j].contains(words[i])) {
ret.add(words[i]);
break;
}
}
}
return ret;
}
}
[sol1-C#]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Solution {
public IList<string> StringMatching(string[] words) {
IList<string> ret = new List<string>();
for (int i = 0; i < words.Length; i++) {
for (int j = 0; j < words.Length; j++) {
if (i != j && words[j].Contains(words[i])) {
ret.Add(words[i]);
break;
}
}
}
return ret;
}
}
[sol1-C]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
char ** stringMatching(char ** words, int wordsSize, int* returnSize){
char **ret = (char **)malloc(sizeof(char *) * wordsSize);
int pos = 0;
for (int i = 0; i < wordsSize; i++) {
for (int j = 0; j < wordsSize; j++) {
if (i != j && strstr(words[j], words[i])) {
ret[pos++] = words[i];
break;
}
}
}
*returnSize = pos;
return ret;
}
[sol1-JavaScript]
1
2
3
4
5
6
7
8
9
10
11
12
var stringMatching = function(words) {
const ret = [];
for (let i = 0; i < words.length; i++) {
for (let j = 0; j < words.length; j++) {
if (i !== j && words[j].search(words[i]) !== -1) {
ret.push(words[i]);
break;
}
}
}
return ret;
};
[sol1-Golang]
1
2
3
4
5
6
7
8
9
10
11
func stringMatching(words []string) (ans []string) {
for i, x := range words {
for j, y := range words {
if j != i && strings.Contains(y, x) {
ans = append(ans, x)
break
}
}
}
return
}

复杂度分析

  • 时间复杂度:O(n^2 \times L^2),其中 n 是字符串数组的长度,L 是字符串数组中最长字符串的长度。使用 KMP 字符串匹配算法可以将时间复杂度优化到 O(n^2 \times T),其中 T 是字符串数组中所有字符串的平均长度。

  • 空间复杂度:O(1)。返回值不计入空间复杂度。如果使用 KMP 字符串匹配算法,那么对应的空间复杂度为 O(T)。

 Comments
On this page
1408-数组中的字符串匹配