Skip to content
Open
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
48 changes: 32 additions & 16 deletions leetcode/2201-2300/2227.Encrypt-and-Decrypt-Strings/README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,44 @@
# [2227.Encrypt and Decrypt Strings][title]

> [!WARNING|style:flat]
> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm)

## Description
You are given a character array `keys` containing unique characters and a string array `values` containing strings of length 2. You are also given another string array `dictionary` that contains all permitted original strings after decryption. You should implement a data structure that can encrypt or decrypt a **0-indexed** string.

**Example 1:**
A string is **encrypted** with the following process:

```
Input: a = "11", b = "1"
Output: "100"
```
1. For each character `c` in the string, we find the index `i` satisfying `keys[i] == c` in `keys`.
2. Replace `c` with `values[i]` in the string.

## 题意
> ...
Note that in case a character of the string is **not present** in `keys`, the encryption process cannot be carried out, and an empty string `""` is returned.

## 题解
A string is **decrypted** with the following process:

### 思路1
> ...
Encrypt and Decrypt Strings
```go
```
1. For each substring `s` of length 2 occurring at an even index in the string, we find an `i` such that `values[i] == s`. If there are multiple valid `i`, we choose **any** one of them. This means a string could have multiple possible strings it can decrypt to.
2. Replace `s` with `keys[i]` in the string.

Implement the `Encrypter` class:

- `Encrypter(char[] keys, String[] values, String[] dictionary)` Initializes the `Encrypter` class with `keys`, `values`, and `dictionary`.
- `String encrypt(String word1)` Encrypts `word1` with the encryption process described above and returns the encrypted string.
- `int decrypt(String word2)` Returns the number of possible strings `word2` could decrypt to that also appear in `dictionary`.

**Example 1:**

```
Input
["Encrypter", "encrypt", "decrypt"]
[[['a', 'b', 'c', 'd'], ["ei", "zf", "ei", "am"], ["abcd", "acbd", "adbc", "badc", "dacb", "cadb", "cbda", "abad"]], ["abcd"], ["eizfeiam"]]
Output
[null, "eizfeiam", 2]

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".
// '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".
// 2 of those strings, "abad" and "abcd", appear in dictionary, so the answer is 2.
```

## 结语

Expand Down
101 changes: 99 additions & 2 deletions leetcode/2201-2300/2227.Encrypt-and-Decrypt-Strings/Solution.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,102 @@
package Solution

func Solution(x bool) bool {
return x
import (
"strings"
)

type trieNode2227 struct {
child [26]*trieNode2227
end bool
}

func buildTrieNode2227(dic []string) *trieNode2227 {
root := &trieNode2227{
child: [26]*trieNode2227{},
}
for _, word := range dic {
walker := root
for _, b := range []byte(word) {
index := b - 'a'
if walker.child[index] == nil {
walker.child[index] = &trieNode2227{}
}
walker = walker.child[index]
}
walker.end = true
}
return root
}

type Encrypter struct {
tree *trieNode2227
keys []byte
keysMap map[byte]int
values []string
valuesMapper map[string][]int
}

func Constructor(keys []byte, values []string, dictionary []string) Encrypter {
tree := buildTrieNode2227(dictionary)
e := Encrypter{
tree: tree,
keys: keys,
keysMap: make(map[byte]int),
values: values,
valuesMapper: map[string][]int{},
}
for i, b := range keys {
e.keysMap[b] = i
}
for i, str := range values {
if _, ok := e.valuesMapper[str]; !ok {
e.valuesMapper[str] = []int{}
}
e.valuesMapper[str] = append(e.valuesMapper[str], i)
}

return e
}

func (this *Encrypter) Encrypt(word1 string) string {
buf := strings.Builder{}
for _, b := range []byte(word1) {
index, ok := this.keysMap[b]
if !ok {
return ""
}

buf.WriteString(this.values[index])
}
return buf.String()
}

func (this *Encrypter) search(word2 string, index int, tree *trieNode2227) int {
if index >= len(word2) {
if tree.end {
return 1
}
return 0
}
// ab -> c, c
cur := word2[index : index+2]
var ret int
for _, i := range this.valuesMapper[cur] {
childIndex := this.keys[i] - 'a'
if tree.child[childIndex] == nil {
continue
}
ret += this.search(word2, index+2, tree.child[childIndex])
}
return ret
}
func (this *Encrypter) Decrypt(word2 string) int {
return this.search(word2, 0, this.tree)
}

func Solution(keys []byte, values []string, dictionary []string, encryptStr, decryptStr string) []any {
c := Constructor(keys, values, dictionary)
var ret []any
ret = append(ret, c.Encrypt(encryptStr))
ret = append(ret, c.Decrypt(decryptStr))
return ret
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,31 @@ import (
func TestSolution(t *testing.T) {
// 测试用例
cases := []struct {
name string
inputs bool
expect bool
name string
keys []byte
values, dictionary []string
word1, word2 string
expect []any
}{
{"TestCase", true, true},
{"TestCase", true, true},
{"TestCase", false, false},
{"TestCase1", []byte{'a', 'b', 'c', 'd'}, []string{"ei", "zf", "ei", "am"}, []string{"abcd", "acbd", "adbc", "badc", "dacb", "cadb", "cbda", "abad"}, "abcd", "eizfeiam", []any{"eizfeiam", 2}},
}

// 开始测试
for i, c := range cases {
t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) {
got := Solution(c.inputs)
got := Solution(c.keys, c.values, c.dictionary, c.word1, c.word2)
if !reflect.DeepEqual(got, c.expect) {
t.Fatalf("expected: %v, but got: %v, with inputs: %v",
c.expect, got, c.inputs)
t.Fatalf("expected: %v, but got: %v, with inputs: %v %v %v %v %v",
c.expect, got, c.keys, c.values, c.dictionary, c.word1, c.word2)
}
})
}
}

// 压力测试
// 压力测试
func BenchmarkSolution(b *testing.B) {
}

// 使用案列
// 使用案列
func ExampleSolution() {
}
Loading