📅  最后修改于: 2023-12-03 15:12:47.185000             🧑  作者: Mango
给定一个字符串 s 和一个字符串列表 dict ,你需要将所有在字符串列表中出现过的 s 的子串替换为 "*" 。
输入:
s = "leetcode"
dict = ["leet", "code"]
输出:
"*****ode"
本题的基本思路是,遍历字符串列表dict,对于每个字符串,判断其是否是s的子串。如果是,则将其替换为"***"。
具体实现有多种方式,例如暴力枚举、Trie树等。在本文中,我们将介绍一种基于Trie树的解法。
from typing import List
class TrieNode:
def __init__(self):
self.children = {}
self.isEnd = False
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, word: str) -> None:
node = self.root
for c in word:
if c not in node.children:
node.children[c] = TrieNode()
node = node.children[c]
node.isEnd = True
def search(self, word: str) -> bool:
node = self.root
for c in word:
if c not in node.children:
return False
node = node.children[c]
return node.isEnd
class Solution:
def replaceWords(self, dict: List[str], s: str) -> str:
trie = Trie()
for word in dict:
trie.insert(word)
words = s.split()
res = []
for word in words:
for i in range(len(word)):
if trie.search(word[:i]):
res.append("*" * len(word))
break
else:
res.append(word)
return " ".join(res)
class TrieNode {
Map<Character, TrieNode> children;
boolean isEnd;
public TrieNode() {
children = new HashMap<>();
isEnd = false;
}
}
class Trie {
TrieNode root;
public Trie() {
root = new TrieNode();
}
public void insert(String word) {
TrieNode node = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (!node.children.containsKey(c)) {
node.children.put(c, new TrieNode());
}
node = node.children.get(c);
}
node.isEnd = true;
}
public boolean search(String word) {
TrieNode node = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (!node.children.containsKey(c)) {
return false;
}
node = node.children.get(c);
if (node.isEnd) {
return true;
}
}
return false;
}
}
class Solution {
public String replaceWords(List<String> dict, String s) {
Trie trie = new Trie();
for (String word : dict) {
trie.insert(word);
}
String[] words = s.split("\\s+");
StringBuilder sb = new StringBuilder();
for (String word : words) {
boolean flag = false;
StringBuilder temp = new StringBuilder();
for (int i = 1; i <= word.length(); i++) {
String prefix = word.substring(0, i);
if (trie.search(prefix)) {
temp.append("*".repeat(word.length()));
flag = true;
break;
} else {
temp.append(word.charAt(i - 1));
}
}
if (!flag) {
temp.append(word);
}
sb.append(temp.toString() + " ");
}
return sb.toString().trim();
}
}
本题重点在于如何快速判断一个字符串是否是另一个字符串的前缀。可以使用Trie树进行优化。时间复杂度为O(NM),其中N为字符串s的长度,M为字符串列表dict中所有字符串的长度和。