Skip to content

feat: add solutions to lc problem: No.0676 #2053

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
518 changes: 341 additions & 177 deletions solution/0600-0699/0676.Implement Magic Dictionary/README.md

Large diffs are not rendered by default.

510 changes: 344 additions & 166 deletions solution/0600-0699/0676.Implement Magic Dictionary/README_EN.md

Large diffs are not rendered by default.

112 changes: 71 additions & 41 deletions solution/0600-0699/0676.Implement Magic Dictionary/Solution.cpp
Original file line number Diff line number Diff line change
@@ -1,42 +1,72 @@
class MagicDictionary {
public:
/** Initialize your data structure here. */
MagicDictionary() {
}

void buildDict(vector<string> dictionary) {
for (string word : dictionary) {
s.insert(word);
for (string p : gen(word)) ++cnt[p];
}
}

bool search(string searchWord) {
for (string p : gen(searchWord)) {
if (cnt[p] > 1 || (cnt[p] == 1 && !s.count(searchWord))) return true;
}
return false;
}

private:
unordered_set<string> s;
unordered_map<string, int> cnt;

vector<string> gen(string word) {
vector<string> res;
for (int i = 0; i < word.size(); ++i) {
char c = word[i];
word[i] = '*';
res.push_back(word);
word[i] = c;
}
return res;
}
};

/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary* obj = new MagicDictionary();
* obj->buildDict(dictionary);
* bool param_2 = obj->search(searchWord);
class Trie {
private:
Trie* children[26];
bool isEnd = false;

public:
Trie() {
fill(begin(children), end(children), nullptr);
}

void insert(const string& w) {
Trie* node = this;
for (char c : w) {
int i = c - 'a';
if (!node->children[i]) {
node->children[i] = new Trie();
}
node = node->children[i];
}
node->isEnd = true;
}

bool search(const string& w) {
function<bool(int, Trie*, int)> dfs = [&](int i, Trie* node, int diff) {
if (i >= w.size()) {
return diff == 1 && node->isEnd;
}
int j = w[i] - 'a';
if (node->children[j] && dfs(i + 1, node->children[j], diff)) {
return true;
}
if (diff == 0) {
for (int k = 0; k < 26; ++k) {
if (k != j && node->children[k]) {
if (dfs(i + 1, node->children[k], 1)) {
return true;
}
}
}
}
return false;
};
return dfs(0, this, 0);
}
};

class MagicDictionary {
public:
MagicDictionary() {
trie = new Trie();
}

void buildDict(vector<string> dictionary) {
for (auto& w : dictionary) {
trie->insert(w);
}
}

bool search(string searchWord) {
return trie->search(searchWord);
}

private:
Trie* trie;
};

/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary* obj = new MagicDictionary();
* obj->buildDict(dictionary);
* bool param_2 = obj->search(searchWord);
*/
65 changes: 45 additions & 20 deletions solution/0600-0699/0676.Implement Magic Dictionary/Solution.go
Original file line number Diff line number Diff line change
@@ -1,37 +1,62 @@
type MagicDictionary struct {
s map[string]bool
cnt map[string]int
type Trie struct {
children [26]*Trie
isEnd bool
}

/** Initialize your data structure here. */
func Constructor() MagicDictionary {
return MagicDictionary{map[string]bool{}, map[string]int{}}
func NewTrie() *Trie {
return &Trie{}
}

func (this *MagicDictionary) BuildDict(dictionary []string) {
for _, word := range dictionary {
this.s[word] = true
for _, p := range gen(word) {
this.cnt[p]++
func (t *Trie) Insert(w string) {
node := t
for _, c := range w {
i := c - 'a'
if node.children[i] == nil {
node.children[i] = NewTrie()
}
node = node.children[i]
}
node.isEnd = true
}

func (this *MagicDictionary) Search(searchWord string) bool {
for _, p := range gen(searchWord) {
if this.cnt[p] > 1 || (this.cnt[p] == 1 && !this.s[searchWord]) {
func (t *Trie) Search(w string) bool {
var dfs func(int, *Trie, int) bool
dfs = func(i int, node *Trie, diff int) bool {
if i >= len(w) {
return diff == 1 && node.isEnd
}
j := int(w[i] - 'a')
if node.children[j] != nil && dfs(i+1, node.children[j], diff) {
return true
}
if diff == 0 {
for k := 0; k < 26; k++ {
if k != j && node.children[k] != nil && dfs(i+1, node.children[k], 1) {
return true
}
}
}
return false
}
return false
return dfs(0, t, 0)
}

type MagicDictionary struct {
trie *Trie
}

func Constructor() MagicDictionary {
return MagicDictionary{trie: NewTrie()}
}

func gen(word string) []string {
var res []string
for i := 0; i < len(word); i++ {
res = append(res, word[:i]+"."+word[i+1:])
func (md *MagicDictionary) BuildDict(dictionary []string) {
for _, w := range dictionary {
md.trie.Insert(w)
}
return res
}

func (md *MagicDictionary) Search(searchWord string) bool {
return md.trie.Search(searchWord)
}

/**
Expand Down
110 changes: 65 additions & 45 deletions solution/0600-0699/0676.Implement Magic Dictionary/Solution.java
Original file line number Diff line number Diff line change
@@ -1,46 +1,66 @@
class MagicDictionary {
private Set<String> s = new HashSet<>();
private Map<String, Integer> cnt = new HashMap<>();

/** Initialize your data structure here. */
public MagicDictionary() {
}

public void buildDict(String[] dictionary) {
for (String word : dictionary) {
s.add(word);
for (String p : gen(word)) {
cnt.put(p, cnt.getOrDefault(p, 0) + 1);
}
}
}

public boolean search(String searchWord) {
for (String p : gen(searchWord)) {
int v = cnt.getOrDefault(p, 0);
if (v > 1 || (v == 1 && !s.contains(searchWord))) {
return true;
}
}
return false;
}

private List<String> gen(String word) {
List<String> res = new ArrayList<>();
char[] chars = word.toCharArray();
for (int i = 0; i < chars.length; ++i) {
char c = chars[i];
chars[i] = '*';
res.add(new String(chars));
chars[i] = c;
}
return res;
}
}

/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary obj = new MagicDictionary();
* obj.buildDict(dictionary);
* boolean param_2 = obj.search(searchWord);
class Trie {
private Trie[] children = new Trie[26];
private boolean isEnd;

public void insert(String w) {
Trie node = this;
for (char c : w.toCharArray()) {
int i = c - 'a';
if (node.children[i] == null) {
node.children[i] = new Trie();
}
node = node.children[i];
}
node.isEnd = true;
}

public boolean search(String w) {
return dfs(w, 0, this, 0);
}

private boolean dfs(String w, int i, Trie node, int diff) {
if (i == w.length()) {
return diff == 1 && node.isEnd;
}
int j = w.charAt(i) - 'a';
if (node.children[j] != null) {
if (dfs(w, i + 1, node.children[j], diff)) {
return true;
}
}
if (diff == 0) {
for (int k = 0; k < 26; k++) {
if (k != j && node.children[k] != null) {
if (dfs(w, i + 1, node.children[k], 1)) {
return true;
}
}
}
}
return false;
}
}

class MagicDictionary {
private Trie trie = new Trie();

public MagicDictionary() {
}

public void buildDict(String[] dictionary) {
for (String w : dictionary) {
trie.insert(w);
}
}

public boolean search(String searchWord) {
return trie.search(searchWord);
}
}

/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary obj = new MagicDictionary();
* obj.buildDict(dictionary);
* boolean param_2 = obj.search(searchWord);
*/
68 changes: 44 additions & 24 deletions solution/0600-0699/0676.Implement Magic Dictionary/Solution.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,44 @@
class MagicDictionary:
def __init__(self):
"""
Initialize your data structure here.
"""

def gen(self, word):
return [word[:i] + '*' + word[i + 1 :] for i in range(len(word))]

def buildDict(self, dictionary: List[str]) -> None:
self.s = set(dictionary)
self.cnt = Counter(p for word in dictionary for p in self.gen(word))

def search(self, searchWord: str) -> bool:
for p in self.gen(searchWord):
if self.cnt[p] > 1 or (self.cnt[p] == 1 and searchWord not in self.s):
return True
return False


# Your MagicDictionary object will be instantiated and called as such:
# obj = MagicDictionary()
# obj.buildDict(dictionary)
# param_2 = obj.search(searchWord)
class Trie:
__slots__ = ["children", "is_end"]

def __init__(self):
self.children = {}
self.is_end = False

def insert(self, w: str) -> None:
node = self
for c in w:
if c not in node.children:
node.children[c] = Trie()
node = node.children[c]
node.is_end = True

def search(self, w: str) -> bool:
def dfs(i: int, node: Trie, diff: int) -> bool:
if i == len(w):
return diff == 1 and node.is_end
if w[i] in node.children and dfs(i + 1, node.children[w[i]], diff):
return True
return diff == 0 and any(
dfs(i + 1, node.children[c], 1) for c in node.children if c != w[i]
)

return dfs(0, self, 0)


class MagicDictionary:
def __init__(self):
self.trie = Trie()

def buildDict(self, dictionary: List[str]) -> None:
for w in dictionary:
self.trie.insert(w)

def search(self, searchWord: str) -> bool:
return self.trie.search(searchWord)


# Your MagicDictionary object will be instantiated and called as such:
# obj = MagicDictionary()
# obj.buildDict(dictionary)
# param_2 = obj.search(searchWord)
Loading