携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情
题目描述
给你一个字符串数组 words ,数组中的每个字符串都可以看作是一个单词。请你按 任意 顺序返回 words 中是其他单词的子字符串的所有单词。
如果你可以删除 words[j] 最左侧和/或最右侧的若干字符得到 word[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"]
输出:[]
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/string-matching-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路分析
- 今天的算法题目是字符串数组匹配题目,题目稍微有些繁琐,简单理解就是求字符串 words[i]的子串的个数。
- 分析题目,求子串,我们可以明显得到长度短的字符串可能是长度长的字符串的子串。根据这个结论,我们使用数组排序,按照字符串的长度进行升序排序。在代码实践中,就是重载 Comparator,实现自定义的排序操作。
- 对于排序完成的字符串数组,我们可以使用排序的方式,先从尾部取出words[i],在从头部开始,依次取出words[j], 判断 words[j] 是不是words[i]的子串即可。
- 这里需要注意的是,在返回的结果中,words 字符串不能重复,需要注意一下去重。具体实现代码如下,供参考。
通过代码
class Solution {
public List<String> stringMatching(String[] words) {
List<String> ans = new ArrayList<>();
int n = words.length;
Arrays.sort(words, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
});
for (int i = n - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {
if (words[i].indexOf(words[j]) != -1) {
if (ans.contains(words[j])) {
continue;
}
ans.add(words[j]);
}
}
}
return ans;
}
}
总结
- 上述算法的时间复杂度是O(n log (n)), 空间复杂度是O(n)
- 坚持算法每日一题,加油!