diff --git a/solution/2200-2299/2227.Encrypt and Decrypt Strings/README.md b/solution/2200-2299/2227.Encrypt and Decrypt Strings/README.md index 6401e5a1cf2f7..07bf56db922af 100644 --- a/solution/2200-2299/2227.Encrypt and Decrypt Strings/README.md +++ b/solution/2200-2299/2227.Encrypt and Decrypt Strings/README.md @@ -61,11 +61,11 @@ tags: 解释: Encrypter encrypter = new Encrypter([['a', 'b', 'c', 'd'], ["ei", "zf", "ei", "am"], ["abcd", "acbd", "adbc", "badc", "dacb", "cadb", "cbda", "abad"]); -encrypter.encrypt("abcd"); // 返回 "eizfeiam"。 +encrypter.encrypt("abcd"); // 返回 "eizfeiam"。   // 'a' 映射为 "ei",'b' 映射为 "zf",'c' 映射为 "ei",'d' 映射为 "am"。 -encrypter.decrypt("eizfeiam"); // return 2. - // "ei" 可以映射为 'a' 或 'c',"zf" 映射为 'b',"am" 映射为 'd'。 - // 因此,解密后可以得到的字符串是 "abad","cbad","abcd" 和 "cbcd"。 +encrypter.decrypt("eizfeiam"); // return 2. + // "ei" 可以映射为 'a' 或 'c',"zf" 映射为 'b',"am" 映射为 'd'。 + // 因此,解密后可以得到的字符串是 "abad","cbad","abcd" 和 "cbcd"。 // 其中 2 个字符串,"abad" 和 "abcd",在 dictionary 中出现,所以答案是 2 。 @@ -95,6 +95,16 @@ encrypter.decrypt("eizfeiam"); // return 2. ### 方法一:哈希表 +我们用一个哈希表 $\textit{mp}$ 记录每个字符的加密结果,用另一个哈希表 $\textit{cnt}$ 记录每个加密结果出现的次数。 + +在构造函数中,我们遍历 $\textit{keys}$ 和 $\textit{values}$,将每个字符和其对应的加密结果存入 $\textit{mp}$ 中。然后遍历 $\textit{dictionary}$,统计每个加密结果出现的次数。时间复杂度 $(n + m)$,其中 $n$ 和 $m$ 分别是 $\textit{keys}$ 和 $\textit{dictionary}$ 的长度。 + +在加密函数中,我们遍历输入字符串 $\textit{word1}$ 的每个字符,查找其加密结果并拼接起来。如果某个字符没有对应的加密结果,说明无法加密,返回空字符串。时间复杂度 $O(k)$,其中 $k$ 是 $\textit{word1}$ 的长度。 + +在解密函数中,我们直接返回 $\textit{cnt}$ 中 $\textit{word2}$ 对应的次数。时间复杂度 $O(1)$。 + +空间复杂度 $O(n + m)$。 + #### Python3 @@ -135,8 +145,7 @@ class Encrypter { mp.put(keys[i], values[i]); } for (String w : dictionary) { - w = encrypt(w); - cnt.put(w, cnt.getOrDefault(w, 0) + 1); + cnt.merge(encrypt(w), 1, Integer::sum); } } @@ -173,14 +182,20 @@ public: unordered_map mp; Encrypter(vector& keys, vector& values, vector& dictionary) { - for (int i = 0; i < keys.size(); ++i) mp[keys[i]] = values[i]; - for (auto v : dictionary) cnt[encrypt(v)]++; + for (int i = 0; i < keys.size(); ++i) { + mp[keys[i]] = values[i]; + } + for (auto v : dictionary) { + cnt[encrypt(v)]++; + } } string encrypt(string word1) { string res = ""; for (char c : word1) { - if (!mp.count(c)) return ""; + if (!mp.count(c)) { + return ""; + } res += mp[c]; } return res; @@ -244,6 +259,49 @@ func (this *Encrypter) Decrypt(word2 string) int { */ ``` +#### TypeScript + +```ts +class Encrypter { + private mp: Map = new Map(); + private cnt: Map = new Map(); + + constructor(keys: string[], values: string[], dictionary: string[]) { + for (let i = 0; i < keys.length; i++) { + this.mp.set(keys[i], values[i]); + } + for (const w of dictionary) { + const encrypted = this.encrypt(w); + if (encrypted !== '') { + this.cnt.set(encrypted, (this.cnt.get(encrypted) || 0) + 1); + } + } + } + + encrypt(word: string): string { + let res = ''; + for (const c of word) { + if (!this.mp.has(c)) { + return ''; + } + res += this.mp.get(c); + } + return res; + } + + decrypt(word: string): number { + return this.cnt.get(word) || 0; + } +} + +/** + * Your Encrypter object will be instantiated and called as such: + * const obj = new Encrypter(keys, values, dictionary); + * const param_1 = obj.encrypt(word1); + * const param_2 = obj.decrypt(word2); + */ +``` + diff --git a/solution/2200-2299/2227.Encrypt and Decrypt Strings/README_EN.md b/solution/2200-2299/2227.Encrypt and Decrypt Strings/README_EN.md index 08801fbec5262..6577eeb659157 100644 --- a/solution/2200-2299/2227.Encrypt and Decrypt Strings/README_EN.md +++ b/solution/2200-2299/2227.Encrypt and Decrypt Strings/README_EN.md @@ -60,11 +60,11 @@ tags: Explanation Encrypter encrypter = new Encrypter([['a', 'b', 'c', 'd'], ["ei", "zf", "ei", "am"], ["abcd", "acbd", "adbc", "badc", "dacb", "cadb", "cbda", "abad"]); -encrypter.encrypt("abcd"); // return "eizfeiam". +encrypter.encrypt("abcd"); // return "eizfeiam".   // 'a' maps to "ei", 'b' maps to "zf", 'c' maps to "ei", and 'd' maps to "am". -encrypter.decrypt("eizfeiam"); // return 2. - // "ei" can map to 'a' or 'c', "zf" maps to 'b', and "am" maps to 'd'. - // Thus, the possible strings after decryption are "abad", "cbad", "abcd", and "cbcd". +encrypter.decrypt("eizfeiam"); // return 2. + // "ei" can map to 'a' or 'c', "zf" maps to 'b', and "am" maps to 'd'. + // Thus, the possible strings after decryption are "abad", "cbad", "abcd", and "cbcd". // 2 of those strings, "abad" and "abcd", appear in dictionary, so the answer is 2. @@ -91,7 +91,17 @@ encrypter.decrypt("eizfeiam"); // return 2. -### Solution 1 +### Solution 1: Hash Table + +We use a hash table $\textit{mp}$ to record the encryption result of each character, and another hash table $\textit{cnt}$ to record the number of occurrences of each encryption result. + +In the constructor, we traverse $\textit{keys}$ and $\textit{values}$, storing each character and its corresponding encryption result in $\textit{mp}$. Then, we traverse $\textit{dictionary}$ to count the occurrences of each encryption result. The time complexity is $O(n + m)$, where $n$ and $m$ are the lengths of $\textit{keys}$ and $\textit{dictionary}$, respectively. + +In the encryption function, we traverse each character of the input string $\textit{word1}$, look up its encryption result, and concatenate them. If a character does not have a corresponding encryption result, it means encryption is not possible, and we return an empty string. The time complexity is $O(k)$, where $k$ is the length of $\textit{word1}$. + +In the decryption function, we directly return the count of $\textit{word2}$ in $\textit{cnt}$. The time complexity is $O(1)$. + +The space complexity is $O(n + m)$. @@ -133,8 +143,7 @@ class Encrypter { mp.put(keys[i], values[i]); } for (String w : dictionary) { - w = encrypt(w); - cnt.put(w, cnt.getOrDefault(w, 0) + 1); + cnt.merge(encrypt(w), 1, Integer::sum); } } @@ -171,14 +180,20 @@ public: unordered_map mp; Encrypter(vector& keys, vector& values, vector& dictionary) { - for (int i = 0; i < keys.size(); ++i) mp[keys[i]] = values[i]; - for (auto v : dictionary) cnt[encrypt(v)]++; + for (int i = 0; i < keys.size(); ++i) { + mp[keys[i]] = values[i]; + } + for (auto v : dictionary) { + cnt[encrypt(v)]++; + } } string encrypt(string word1) { string res = ""; for (char c : word1) { - if (!mp.count(c)) return ""; + if (!mp.count(c)) { + return ""; + } res += mp[c]; } return res; @@ -242,6 +257,49 @@ func (this *Encrypter) Decrypt(word2 string) int { */ ``` +#### TypeScript + +```ts +class Encrypter { + private mp: Map = new Map(); + private cnt: Map = new Map(); + + constructor(keys: string[], values: string[], dictionary: string[]) { + for (let i = 0; i < keys.length; i++) { + this.mp.set(keys[i], values[i]); + } + for (const w of dictionary) { + const encrypted = this.encrypt(w); + if (encrypted !== '') { + this.cnt.set(encrypted, (this.cnt.get(encrypted) || 0) + 1); + } + } + } + + encrypt(word: string): string { + let res = ''; + for (const c of word) { + if (!this.mp.has(c)) { + return ''; + } + res += this.mp.get(c); + } + return res; + } + + decrypt(word: string): number { + return this.cnt.get(word) || 0; + } +} + +/** + * Your Encrypter object will be instantiated and called as such: + * const obj = new Encrypter(keys, values, dictionary); + * const param_1 = obj.encrypt(word1); + * const param_2 = obj.decrypt(word2); + */ +``` + diff --git a/solution/2200-2299/2227.Encrypt and Decrypt Strings/Solution.cpp b/solution/2200-2299/2227.Encrypt and Decrypt Strings/Solution.cpp index 12f376c62711e..62c2790efa474 100644 --- a/solution/2200-2299/2227.Encrypt and Decrypt Strings/Solution.cpp +++ b/solution/2200-2299/2227.Encrypt and Decrypt Strings/Solution.cpp @@ -4,14 +4,20 @@ class Encrypter { unordered_map mp; Encrypter(vector& keys, vector& values, vector& dictionary) { - for (int i = 0; i < keys.size(); ++i) mp[keys[i]] = values[i]; - for (auto v : dictionary) cnt[encrypt(v)]++; + for (int i = 0; i < keys.size(); ++i) { + mp[keys[i]] = values[i]; + } + for (auto v : dictionary) { + cnt[encrypt(v)]++; + } } string encrypt(string word1) { string res = ""; for (char c : word1) { - if (!mp.count(c)) return ""; + if (!mp.count(c)) { + return ""; + } res += mp[c]; } return res; @@ -27,4 +33,4 @@ class Encrypter { * Encrypter* obj = new Encrypter(keys, values, dictionary); * string param_1 = obj->encrypt(word1); * int param_2 = obj->decrypt(word2); - */ \ No newline at end of file + */ diff --git a/solution/2200-2299/2227.Encrypt and Decrypt Strings/Solution.java b/solution/2200-2299/2227.Encrypt and Decrypt Strings/Solution.java index 49a9823b70bef..4e40f3d8f174e 100644 --- a/solution/2200-2299/2227.Encrypt and Decrypt Strings/Solution.java +++ b/solution/2200-2299/2227.Encrypt and Decrypt Strings/Solution.java @@ -7,8 +7,7 @@ public Encrypter(char[] keys, String[] values, String[] dictionary) { mp.put(keys[i], values[i]); } for (String w : dictionary) { - w = encrypt(w); - cnt.put(w, cnt.getOrDefault(w, 0) + 1); + cnt.merge(encrypt(w), 1, Integer::sum); } } @@ -33,4 +32,4 @@ public int decrypt(String word2) { * Encrypter obj = new Encrypter(keys, values, dictionary); * String param_1 = obj.encrypt(word1); * int param_2 = obj.decrypt(word2); - */ \ No newline at end of file + */ diff --git a/solution/2200-2299/2227.Encrypt and Decrypt Strings/Solution.ts b/solution/2200-2299/2227.Encrypt and Decrypt Strings/Solution.ts new file mode 100644 index 0000000000000..1e283575c6d68 --- /dev/null +++ b/solution/2200-2299/2227.Encrypt and Decrypt Strings/Solution.ts @@ -0,0 +1,38 @@ +class Encrypter { + private mp: Map = new Map(); + private cnt: Map = new Map(); + + constructor(keys: string[], values: string[], dictionary: string[]) { + for (let i = 0; i < keys.length; i++) { + this.mp.set(keys[i], values[i]); + } + for (const w of dictionary) { + const encrypted = this.encrypt(w); + if (encrypted !== '') { + this.cnt.set(encrypted, (this.cnt.get(encrypted) || 0) + 1); + } + } + } + + encrypt(word: string): string { + let res = ''; + for (const c of word) { + if (!this.mp.has(c)) { + return ''; + } + res += this.mp.get(c); + } + return res; + } + + decrypt(word: string): number { + return this.cnt.get(word) || 0; + } +} + +/** + * Your Encrypter object will be instantiated and called as such: + * const obj = new Encrypter(keys, values, dictionary); + * const param_1 = obj.encrypt(word1); + * const param_2 = obj.decrypt(word2); + */