diff --git a/solution/0300-0399/0320.Generalized Abbreviation/README.md b/solution/0300-0399/0320.Generalized Abbreviation/README.md index c69d61e4fce19..9f621500aa650 100644 --- a/solution/0300-0399/0320.Generalized Abbreviation/README.md +++ b/solution/0300-0399/0320.Generalized Abbreviation/README.md @@ -54,10 +54,30 @@ ## 解法 -回溯法。 - +**方法一:DFS** + +我们设计一个函数 $dfs(i)$,表示对于字符串 $word[i:]$,返回其所有可能的缩写。 + +函数 $dfs(i)$ 的执行逻辑如下: + +如果 $i \geq n$,说明已经处理完了字符串 $word$,直接返回一个空字符串组成的列表。 + +否则,我们可以选择保留 $word[i]$,然后对 $dfs(i + 1)$ 返回的列表中的每个字符串前面添加 $word[i]$,将得到的结果添加到答案中。 + +我们也可以选择删除 $word[i]$ 及其后面的若干个字符,假设我们删除了 $word[i..j)$,那么第 $j$ 个字符不删除,然后对 $dfs(j + 1)$ 返回的列表中的每个字符串前面添加 $j - i$,将得到的结果添加到答案中。 + +最后,我们在主函数中调用 $dfs(0)$ 即可。 + +时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 是字符串 $word$ 的长度。 + +**方法二:二进制枚举** + +由于字符串 $word$ 的长度不超过 $15$,因此我们可以使用二进制枚举的方法枚举所有的缩写。我们用一个长度为 $n$ 的二进制数 $i$ 表示一种缩写方式,其中 $0$ 表示保留对应的字符,而 $1$ 表示删除对应的字符。我们在 $[0, 2^n)$ 的范围内枚举所有 $i$,并将其转换成对应的缩写,添加到答案列表中即可。 + +时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 是字符串 $word$ 的长度。 + ### **Python3** @@ -67,26 +87,38 @@ ```python class Solution: def generateAbbreviations(self, word: str) -> List[str]: - def dfs(s, t): - if not s: - ans.append(''.join(t)) - return - for i in range(1, len(s) + 1): - t.append(str(i)) - if i < len(s): - t.append(s[i]) - dfs(s[i + 1 :], t) - t.pop() - else: - dfs(s[i:], t) - t.pop() - - t.append(s[0]) - dfs(s[1:], t) - t.pop() + def dfs(i: int) -> List[str]: + if i >= n: + return [""] + ans = [word[i] + s for s in dfs(i + 1)] + for j in range(i + 1, n + 1): + for s in dfs(j + 1): + ans.append(str(j - i) + (word[j] if j < n else "") + s) + return ans + + n = len(word) + return dfs(0) +``` +```python +class Solution: + def generateAbbreviations(self, word: str) -> List[str]: + n = len(word) ans = [] - dfs(word, []) + for i in range(1 << n): + cnt = 0 + s = [] + for j in range(n): + if i >> j & 1: + cnt += 1 + else: + if cnt: + s.append(str(cnt)) + cnt = 0 + s.append(word[j]) + if cnt: + s.append(str(cnt)) + ans.append("".join(s)) return ans ``` @@ -96,35 +128,197 @@ class Solution: ```java class Solution { - private List ans; + private String word; + private int n; public List generateAbbreviations(String word) { - ans = new ArrayList<>(); - List t = new ArrayList<>(); - dfs(word, t); + this.word = word; + n = word.length(); + return dfs(0); + } + + private List dfs(int i) { + if (i >= n) { + return List.of(""); + } + List ans = new ArrayList<>(); + for (String s : dfs(i + 1)) { + ans.add(String.valueOf(word.charAt(i)) + s); + } + for (int j = i + 1; j <= n; ++j) { + for (String s : dfs(j + 1)) { + ans.add((j - i) + "" + (j < n ? String.valueOf(word.charAt(j)) : "") + s); + } + } return ans; } +} +``` - private void dfs(String s, List t) { - if ("".equals(s)) { - ans.add(String.join("", t)); - return; +```java +class Solution { + public List generateAbbreviations(String word) { + int n = word.length(); + List ans = new ArrayList<>(); + for (int i = 0; i < 1 << n; ++i) { + StringBuilder s = new StringBuilder(); + int cnt = 0; + for (int j = 0; j < n; ++j) { + if ((i >> j & 1) == 1) { + ++cnt; + } else { + if (cnt > 0) { + s.append(cnt); + cnt = 0; + } + s.append(word.charAt(j)); + } + } + if (cnt > 0) { + s.append(cnt); + } + ans.add(s.toString()); } - for (int i = 1; i < s.length() + 1; ++i) { - t.add(i + ""); - if (i < s.length()) { - t.add(String.valueOf(s.charAt(i))); - dfs(s.substring(i + 1), t); - t.remove(t.size() - 1); - } else { - dfs(s.substring(i), t); + return ans; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + vector generateAbbreviations(string word) { + int n = word.size(); + function(int)> dfs = [&](int i) -> vector { + if (i >= n) { + return {""}; + } + vector ans; + for (auto& s : dfs(i + 1)) { + string p(1, word[i]); + ans.emplace_back(p + s); + } + for (int j = i + 1; j <= n; ++j) { + for (auto& s : dfs(j + 1)) { + string p = j < n ? string(1, word[j]) : ""; + ans.emplace_back(to_string(j - i) + p + s); + } + } + return ans; + }; + return dfs(0); + } +}; +``` + +```cpp +class Solution { +public: + vector generateAbbreviations(string word) { + int n = word.size(); + vector ans; + for (int i = 0; i < 1 << n; ++i) { + string s; + int cnt = 0; + for (int j = 0; j < n; ++j) { + if (i >> j & 1) { + ++cnt; + } else { + if (cnt) { + s += to_string(cnt); + cnt = 0; + } + s.push_back(word[j]); + } + } + if (cnt) { + s += to_string(cnt); } - t.remove(t.size() - 1); + ans.push_back(s); } - t.add(String.valueOf(s.charAt(0))); - dfs(s.substring(1), t); - t.remove(t.size() - 1); + return ans; } +}; +``` + +### **Go** + +```go +func generateAbbreviations(word string) []string { + n := len(word) + var dfs func(int) []string + dfs = func(i int) []string { + if i >= n { + return []string{""} + } + ans := []string{} + for _, s := range dfs(i + 1) { + ans = append(ans, word[i:i+1]+s) + } + for j := i + 1; j <= n; j++ { + for _, s := range dfs(j + 1) { + p := "" + if j < n { + p = word[j : j+1] + } + ans = append(ans, strconv.Itoa(j-i)+p+s) + } + } + return ans + } + return dfs(0) +} +``` + +```go +func generateAbbreviations(word string) (ans []string) { + n := len(word) + for i := 0; i < 1<>j&1 == 1 { + cnt++ + } else { + if cnt > 0 { + s.WriteString(strconv.Itoa(cnt)) + cnt = 0 + } + s.WriteByte(word[j]) + } + } + if cnt > 0 { + s.WriteString(strconv.Itoa(cnt)) + } + ans = append(ans, s.String()) + } + return +} +``` + +### **TypeScript** + +```ts +function generateAbbreviations(word: string): string[] { + const n = word.length; + const dfs = (i: number): string[] => { + if (i >= n) { + return ['']; + } + const ans: string[] = []; + for (const s of dfs(i + 1)) { + ans.push(word[i] + s); + } + for (let j = i + 1; j <= n; ++j) { + for (const s of dfs(j + 1)) { + ans.push((j - i).toString() + (j < n ? word[j] : '') + s); + } + } + return ans; + }; + return dfs(0); } ``` diff --git a/solution/0300-0399/0320.Generalized Abbreviation/README_EN.md b/solution/0300-0399/0320.Generalized Abbreviation/README_EN.md index 12fc2a56a987c..6e27c86f49940 100644 --- a/solution/0300-0399/0320.Generalized Abbreviation/README_EN.md +++ b/solution/0300-0399/0320.Generalized Abbreviation/README_EN.md @@ -43,6 +43,28 @@ ## Solutions +**Solution 1: DFS** + +We design a function $dfs(i)$, which returns all possible abbreviations for the string $word[i:]$. + +The execution logic of the function $dfs(i)$ is as follows: + +If $i \geq n$, it means that the string $word$ has been processed, and we directly return a list composed of an empty string. + +Otherwise, we can choose to keep $word[i]$, and then add $word[i]$ to the front of each string in the list returned by $dfs(i + 1)$, and add the obtained result to the answer. + +We can also choose to delete $word[i]$ and some characters after it. Suppose we delete $word[i..j)$, then the $j$ th character is not deleted, and then add $j - i$ to the front of each string in the list returned by $dfs(j + 1)$, and add the obtained result to the answer. + +Finally, we call $dfs(0)$ in the main function. + +The time complexity is $O(n \times 2^n)$, and the space complexity is $O(n)$. Where $n$ is the length of the string $word$. + +**Solution 2: Binary Enumeration** + +Since the length of the string $word$ does not exceed $15$, we can use the method of binary enumeration to enumerate all abbreviations. We use a binary number $i$ of length $n$ to represent an abbreviation, where $0$ represents keeping the corresponding character, and $1$ represents deleting the corresponding character. We enumerate all $i$ in the range of $[0, 2^n)$, convert it into the corresponding abbreviation, and add it to the answer list. + +The time complexity is $O(n \times 2^n)$, and the space complexity is $O(n)$. Where $n$ is the length of the string $word$. + ### **Python3** @@ -50,26 +72,38 @@ ```python class Solution: def generateAbbreviations(self, word: str) -> List[str]: - def dfs(s, t): - if not s: - ans.append(''.join(t)) - return - for i in range(1, len(s) + 1): - t.append(str(i)) - if i < len(s): - t.append(s[i]) - dfs(s[i + 1 :], t) - t.pop() - else: - dfs(s[i:], t) - t.pop() + def dfs(i: int) -> List[str]: + if i >= n: + return [""] + ans = [word[i] + s for s in dfs(i + 1)] + for j in range(i + 1, n + 1): + for s in dfs(j + 1): + ans.append(str(j - i) + (word[j] if j < n else "") + s) + return ans - t.append(s[0]) - dfs(s[1:], t) - t.pop() + n = len(word) + return dfs(0) +``` +```python +class Solution: + def generateAbbreviations(self, word: str) -> List[str]: + n = len(word) ans = [] - dfs(word, []) + for i in range(1 << n): + cnt = 0 + s = [] + for j in range(n): + if i >> j & 1: + cnt += 1 + else: + if cnt: + s.append(str(cnt)) + cnt = 0 + s.append(word[j]) + if cnt: + s.append(str(cnt)) + ans.append("".join(s)) return ans ``` @@ -77,35 +111,197 @@ class Solution: ```java class Solution { - private List ans; + private String word; + private int n; public List generateAbbreviations(String word) { - ans = new ArrayList<>(); - List t = new ArrayList<>(); - dfs(word, t); + this.word = word; + n = word.length(); + return dfs(0); + } + + private List dfs(int i) { + if (i >= n) { + return List.of(""); + } + List ans = new ArrayList<>(); + for (String s : dfs(i + 1)) { + ans.add(String.valueOf(word.charAt(i)) + s); + } + for (int j = i + 1; j <= n; ++j) { + for (String s : dfs(j + 1)) { + ans.add((j - i) + "" + (j < n ? String.valueOf(word.charAt(j)) : "") + s); + } + } return ans; } +} +``` - private void dfs(String s, List t) { - if ("".equals(s)) { - ans.add(String.join("", t)); - return; +```java +class Solution { + public List generateAbbreviations(String word) { + int n = word.length(); + List ans = new ArrayList<>(); + for (int i = 0; i < 1 << n; ++i) { + StringBuilder s = new StringBuilder(); + int cnt = 0; + for (int j = 0; j < n; ++j) { + if ((i >> j & 1) == 1) { + ++cnt; + } else { + if (cnt > 0) { + s.append(cnt); + cnt = 0; + } + s.append(word.charAt(j)); + } + } + if (cnt > 0) { + s.append(cnt); + } + ans.add(s.toString()); } - for (int i = 1; i < s.length() + 1; ++i) { - t.add(i + ""); - if (i < s.length()) { - t.add(String.valueOf(s.charAt(i))); - dfs(s.substring(i + 1), t); - t.remove(t.size() - 1); - } else { - dfs(s.substring(i), t); + return ans; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + vector generateAbbreviations(string word) { + int n = word.size(); + function(int)> dfs = [&](int i) -> vector { + if (i >= n) { + return {""}; + } + vector ans; + for (auto& s : dfs(i + 1)) { + string p(1, word[i]); + ans.emplace_back(p + s); + } + for (int j = i + 1; j <= n; ++j) { + for (auto& s : dfs(j + 1)) { + string p = j < n ? string(1, word[j]) : ""; + ans.emplace_back(to_string(j - i) + p + s); + } } - t.remove(t.size() - 1); + return ans; + }; + return dfs(0); + } +}; +``` + +```cpp +class Solution { +public: + vector generateAbbreviations(string word) { + int n = word.size(); + vector ans; + for (int i = 0; i < 1 << n; ++i) { + string s; + int cnt = 0; + for (int j = 0; j < n; ++j) { + if (i >> j & 1) { + ++cnt; + } else { + if (cnt) { + s += to_string(cnt); + cnt = 0; + } + s.push_back(word[j]); + } + } + if (cnt) { + s += to_string(cnt); + } + ans.push_back(s); } - t.add(String.valueOf(s.charAt(0))); - dfs(s.substring(1), t); - t.remove(t.size() - 1); + return ans; } +}; +``` + +### **Go** + +```go +func generateAbbreviations(word string) []string { + n := len(word) + var dfs func(int) []string + dfs = func(i int) []string { + if i >= n { + return []string{""} + } + ans := []string{} + for _, s := range dfs(i + 1) { + ans = append(ans, word[i:i+1]+s) + } + for j := i + 1; j <= n; j++ { + for _, s := range dfs(j + 1) { + p := "" + if j < n { + p = word[j : j+1] + } + ans = append(ans, strconv.Itoa(j-i)+p+s) + } + } + return ans + } + return dfs(0) +} +``` + +```go +func generateAbbreviations(word string) (ans []string) { + n := len(word) + for i := 0; i < 1<>j&1 == 1 { + cnt++ + } else { + if cnt > 0 { + s.WriteString(strconv.Itoa(cnt)) + cnt = 0 + } + s.WriteByte(word[j]) + } + } + if cnt > 0 { + s.WriteString(strconv.Itoa(cnt)) + } + ans = append(ans, s.String()) + } + return +} +``` + +### **TypeScript** + +```ts +function generateAbbreviations(word: string): string[] { + const n = word.length; + const dfs = (i: number): string[] => { + if (i >= n) { + return ['']; + } + const ans: string[] = []; + for (const s of dfs(i + 1)) { + ans.push(word[i] + s); + } + for (let j = i + 1; j <= n; ++j) { + for (const s of dfs(j + 1)) { + ans.push((j - i).toString() + (j < n ? word[j] : '') + s); + } + } + return ans; + }; + return dfs(0); } ``` diff --git a/solution/0300-0399/0320.Generalized Abbreviation/Solution.cpp b/solution/0300-0399/0320.Generalized Abbreviation/Solution.cpp new file mode 100644 index 0000000000000..080a647c6476b --- /dev/null +++ b/solution/0300-0399/0320.Generalized Abbreviation/Solution.cpp @@ -0,0 +1,27 @@ +class Solution { +public: + vector generateAbbreviations(string word) { + int n = word.size(); + vector ans; + for (int i = 0; i < 1 << n; ++i) { + string s; + int cnt = 0; + for (int j = 0; j < n; ++j) { + if (i >> j & 1) { + ++cnt; + } else { + if (cnt) { + s += to_string(cnt); + cnt = 0; + } + s.push_back(word[j]); + } + } + if (cnt) { + s += to_string(cnt); + } + ans.push_back(s); + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/0300-0399/0320.Generalized Abbreviation/Solution.go b/solution/0300-0399/0320.Generalized Abbreviation/Solution.go new file mode 100644 index 0000000000000..14fa5930f4d08 --- /dev/null +++ b/solution/0300-0399/0320.Generalized Abbreviation/Solution.go @@ -0,0 +1,23 @@ +func generateAbbreviations(word string) (ans []string) { + n := len(word) + for i := 0; i < 1<>j&1 == 1 { + cnt++ + } else { + if cnt > 0 { + s.WriteString(strconv.Itoa(cnt)) + cnt = 0 + } + s.WriteByte(word[j]) + } + } + if cnt > 0 { + s.WriteString(strconv.Itoa(cnt)) + } + ans = append(ans, s.String()) + } + return +} \ No newline at end of file diff --git a/solution/0300-0399/0320.Generalized Abbreviation/Solution.java b/solution/0300-0399/0320.Generalized Abbreviation/Solution.java index e4bd5b092400f..bf7f45ba5ebfb 100644 --- a/solution/0300-0399/0320.Generalized Abbreviation/Solution.java +++ b/solution/0300-0399/0320.Generalized Abbreviation/Solution.java @@ -1,31 +1,26 @@ class Solution { - private List ans; - public List generateAbbreviations(String word) { - ans = new ArrayList<>(); - List t = new ArrayList<>(); - dfs(word, t); - return ans; - } - - private void dfs(String s, List t) { - if ("".equals(s)) { - ans.add(String.join("", t)); - return; - } - for (int i = 1; i < s.length() + 1; ++i) { - t.add(i + ""); - if (i < s.length()) { - t.add(String.valueOf(s.charAt(i))); - dfs(s.substring(i + 1), t); - t.remove(t.size() - 1); - } else { - dfs(s.substring(i), t); + int n = word.length(); + List ans = new ArrayList<>(); + for (int i = 0; i < 1 << n; ++i) { + StringBuilder s = new StringBuilder(); + int cnt = 0; + for (int j = 0; j < n; ++j) { + if ((i >> j & 1) == 1) { + ++cnt; + } else { + if (cnt > 0) { + s.append(cnt); + cnt = 0; + } + s.append(word.charAt(j)); + } } - t.remove(t.size() - 1); + if (cnt > 0) { + s.append(cnt); + } + ans.add(s.toString()); } - t.add(String.valueOf(s.charAt(0))); - dfs(s.substring(1), t); - t.remove(t.size() - 1); + return ans; } } \ No newline at end of file diff --git a/solution/0300-0399/0320.Generalized Abbreviation/Solution.py b/solution/0300-0399/0320.Generalized Abbreviation/Solution.py index 96ccb6d752c3f..42422287eaaad 100644 --- a/solution/0300-0399/0320.Generalized Abbreviation/Solution.py +++ b/solution/0300-0399/0320.Generalized Abbreviation/Solution.py @@ -1,23 +1,19 @@ class Solution: def generateAbbreviations(self, word: str) -> List[str]: - def dfs(s, t): - if not s: - ans.append(''.join(t)) - return - for i in range(1, len(s) + 1): - t.append(str(i)) - if i < len(s): - t.append(s[i]) - dfs(s[i + 1 :], t) - t.pop() - else: - dfs(s[i:], t) - t.pop() - - t.append(s[0]) - dfs(s[1:], t) - t.pop() - + n = len(word) ans = [] - dfs(word, []) + for i in range(1 << n): + cnt = 0 + s = [] + for j in range(n): + if i >> j & 1: + cnt += 1 + else: + if cnt: + s.append(str(cnt)) + cnt = 0 + s.append(word[j]) + if cnt: + s.append(str(cnt)) + ans.append("".join(s)) return ans diff --git a/solution/0300-0399/0320.Generalized Abbreviation/Solution.ts b/solution/0300-0399/0320.Generalized Abbreviation/Solution.ts new file mode 100644 index 0000000000000..6d10d43b384a2 --- /dev/null +++ b/solution/0300-0399/0320.Generalized Abbreviation/Solution.ts @@ -0,0 +1,24 @@ +function generateAbbreviations(word: string): string[] { + const n = word.length; + const ans: string[] = []; + for (let i = 0; i < 1 << n; ++i) { + const s: string[] = []; + let cnt = 0; + for (let j = 0; j < n; ++j) { + if ((i >> j) & 1) { + ++cnt; + } else { + if (cnt > 0) { + s.push(cnt.toString()); + cnt = 0; + } + s.push(word[j]); + } + } + if (cnt > 0) { + s.push(cnt.toString()); + } + ans.push(s.join('')); + } + return ans; +}