携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
一、题目描述:
给你一个字符串数组 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、通过 Join() 将数组链接成一个字符串 strs ;
2、如果 word[i] 是 另一个 word[j] 的子字符串,那么word[i]在 strs 出现的次数必定大于等于2,即 strs.indexOf(words[i])!=strs.lastIndexOf(words[i]);
3、循环遍历数组
三、AC 代码:
var stringMatching = function(words) {
let strs = words.join(",");
let res = []
for(let i=0; i< words.length; i++){
let first = strs.indexOf(words[i]);
let last = strs.lastIndexOf(words[i]);
if(first!=-1 &&last !=-1 && first!=last ){
res.push(words[i]);
}
}
return res;
}
复制代码
四、总结:
其他解法
暴力法
先从小到大排序,2层循环,当前项跟后面的比较,用Set存储结果并返回。
由于结果可能会存在重复,所以需要去重
words 数组按照单字符串长度排序;
遍历数组,判断第i个字符串 是否为[i+1, wordSize-1] 字符串中元素的子集,找到之后即停止第i个字符串的遍历, 将第i个字符串作为答案存储至words数组。 由于循环下标递增,因此可以不需要重新申请字符串数组做为答案返回。 直接将答案填充至words数组已经遍历过的元素内。
var stringMatching = function(words) {
words.sort((a,b) => a.length - b.length)
let set = new Set()
for(let i = 0;i < words.length - 1;i++) {
for(let j = i + 1;j < words.length;j++) {
if(words[j].indexOf(words[i]) > -1) {
set.add(words[i])
}
}
}
return [...set]
};
复制代码