數組中的字符串匹配
給你一個字符串數組 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"]
輸出:[]
提示:
1 <= words.length <= 100
1 <= words[i].length <= 30
words[i]
僅包含小寫英文字母。- 題目數據 保證 每個
words[i]
都是獨一無二的。
方法一,先排序再比較
按字符串長度從小到大排序,然後再用雙指針法,指針j
指向的字符串與指針i
指向的字符串進行contains
判斷,如果包含,
則將指針i指向的字符串添加到集合中,break
本次內循環,跳到外循環繼續判斷。
package weekly_contest_184;
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<String> stringMatching(String[] words) {
sortWords(words);
List<String> list = new ArrayList<String>();
for (int i = 0; i < words.length-1; i++) {
for (int j = i+1; j < words.length; j++) {
if(words[j].contains(words[i])) {
list.add(words[i]);
break;
}
}
}
return list;
}
private void sortWords(String[] arrStr){
String temp = "";
for (int i = 0; i < arrStr.length; i++) {
for (int j = arrStr.length - 1; j > i; j--) {
if (arrStr[i].length() > arrStr[j].length()) {
temp = arrStr[i];
arrStr[i] = arrStr[j];
arrStr[j] = temp;
}
}
}
}
public static void main(String[] args) {
new Solution().stringMatching(new String [] {"mass","as","hero","superhero"})
.stream().forEach(str->System.out.println(str));
System.out.println();
new Solution().stringMatching(new String [] {"leetcode","et","code"})
.stream().forEach(str->System.out.println(str));
System.out.println();
new Solution().stringMatching(new String [] {"blue","green","bu"})
.stream().forEach(str->System.out.println(str));
}
}
方法二
public List<String> stringMatching(String[] words) {
List<String> res = new ArrayList<>();
for (String word : words) {
for (int i = 0; i < words.length; i++) {
if (word.length() >= words[i].length()) continue;
if (words[i].contains(word)) {
res.add(word);
break;
}
}
}
return res;
}
方法三
class Solution {
public List<String> stringMatching(String[] words) {
ArrayList<String> list = new ArrayList<>();
if (words == null ||words.length <= 1)return list;
Arrays.sort(words,(o1, o2) -> {
if (o1.length() != o2.length()){
return o1.length()-o2.length();
}
return o1.compareTo(o2);
});
HashSet<String> set = new HashSet<>();
//使用Tire樹
root = new TireNode();
for (String word : words) {
char[] chars = word.toCharArray();
for (int i = 0; i < chars.length; i++) {
int index = find(chars, i);
if (index != i){
set.add(new String(chars,i,index-i));
}
}
add(chars);
}
list.addAll(set);
return list;
}
TireNode root;
private void add(char[] chars){
TireNode node = root;
for (char c : chars) {
node = node.add(c - 'a');
}
}
private int find(char[] chars,int index){
TireNode node = root;
TireNode next;
int i = index;
for (; i < chars.length; i++) {
next = node.chrildren[chars[i] - 'a'];
if (next==null)break;
node = next;
}
if (node.tial){
return i;
}
return index;
}
static class TireNode{
boolean tial = true;
TireNode[] chrildren;
public TireNode(){
chrildren = new TireNode[26];
}
public TireNode add(int c){
tial = false;
if (chrildren[c] == null){
chrildren[c] = new TireNode();
}
return chrildren[c];
}
}
}
其他
這道題也可以使用KMP algorithm
來做。