diff --git a/solution/3400-3499/3481.Apply Substitutions/README.md b/solution/3400-3499/3481.Apply Substitutions/README.md index a77ddd32a54fa..9b6bd1d93ffed 100644 --- a/solution/3400-3499/3481.Apply Substitutions/README.md +++ b/solution/3400-3499/3481.Apply Substitutions/README.md @@ -76,32 +76,153 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3481.Ap -### 方法一 +### 方法一:哈希表 + 递归 + +我们用一个哈希表 $\textit{d}$ 来存储替换的映射关系,然后定义一个函数 $\textit{dfs}$ 来递归地替换字符串中的占位符。 + +函数 $\textit{dfs}$ 的执行逻辑如下: + +1. 在字符串 $\textit{s}$ 中查找第一个占位符的起始位置 $i$,如果找不到,则返回 $\textit{s}$; +2. 在字符串 $\textit{s}$ 中查找第一个占位符的结束位置 $j$,如果找不到,则返回 $\textit{s}$; +3. 截取占位符的键值 $key$,然后递归地替换占位符的值 $d[key]$; +4. 返回替换后的字符串。 + +在主函数中,我们调用 $\textit{dfs}$ 函数,传入文本字符串 $\textit{text}$,并返回结果。 + +时间复杂度 $O(m + n \times L)$,空间复杂度 $O(m + n \times L)$。其中 $m$ 为替换映射的长度,而 $n$ 和 $L$ 分别为文本字符串的长度和占位符的平均长度。 #### Python3 ```python - +class Solution: + def applySubstitutions(self, replacements: List[List[str]], text: str) -> str: + def dfs(s: str) -> str: + i = s.find("%") + if i == -1: + return s + j = s.find("%", i + 1) + if j == -1: + return s + key = s[i + 1 : j] + replacement = dfs(d[key]) + return s[:i] + replacement + dfs(s[j + 1 :]) + + d = {s: t for s, t in replacements} + return dfs(text) ``` #### Java ```java - +class Solution { + private final Map d = new HashMap<>(); + + public String applySubstitutions(List> replacements, String text) { + for (List e : replacements) { + d.put(e.get(0), e.get(1)); + } + return dfs(text); + } + + private String dfs(String s) { + int i = s.indexOf("%"); + if (i == -1) { + return s; + } + int j = s.indexOf("%", i + 1); + if (j == -1) { + return s; + } + String key = s.substring(i + 1, j); + String replacement = dfs(d.getOrDefault(key, "")); + return s.substring(0, i) + replacement + dfs(s.substring(j + 1)); + } +} ``` #### C++ ```cpp - +class Solution { +public: + string applySubstitutions(vector>& replacements, string text) { + unordered_map d; + for (const auto& e : replacements) { + d[e[0]] = e[1]; + } + auto dfs = [&](this auto&& dfs, const string& s) -> string { + size_t i = s.find('%'); + if (i == string::npos) { + return s; + } + size_t j = s.find('%', i + 1); + if (j == string::npos) { + return s; + } + string key = s.substr(i + 1, j - i - 1); + string replacement = dfs(d[key]); + return s.substr(0, i) + replacement + dfs(s.substr(j + 1)); + }; + return dfs(text); + } +}; ``` #### Go ```go +func applySubstitutions(replacements [][]string, text string) string { + d := make(map[string]string) + for _, e := range replacements { + d[e[0]] = e[1] + } + var dfs func(string) string + dfs = func(s string) string { + i := strings.Index(s, "%") + if i == -1 { + return s + } + j := strings.Index(s[i+1:], "%") + if j == -1 { + return s + } + j += i + 1 + key := s[i+1 : j] + replacement := dfs(d[key]) + return s[:i] + replacement + dfs(s[j+1:]) + } + + return dfs(text) +} +``` +#### TypeScript + +```ts +function applySubstitutions(replacements: string[][], text: string): string { + const d: Record = {}; + for (const [key, value] of replacements) { + d[key] = value; + } + + const dfs = (s: string): string => { + const i = s.indexOf('%'); + if (i === -1) { + return s; + } + const j = s.indexOf('%', i + 1); + if (j === -1) { + return s; + } + const key = s.slice(i + 1, j); + const replacement = dfs(d[key] ?? ''); + return s.slice(0, i) + replacement + dfs(s.slice(j + 1)); + }; + + return dfs(text); +} ``` diff --git a/solution/3400-3499/3481.Apply Substitutions/README_EN.md b/solution/3400-3499/3481.Apply Substitutions/README_EN.md index cf9b3675cba5e..299e46c724f02 100644 --- a/solution/3400-3499/3481.Apply Substitutions/README_EN.md +++ b/solution/3400-3499/3481.Apply Substitutions/README_EN.md @@ -76,32 +76,153 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3481.Ap -### Solution 1 +### Solution 1: Hash Table + Recursion + +We use a hash table $\textit{d}$ to store the substitution mapping, and then define a function $\textit{dfs}$ to recursively replace the placeholders in the string. + +The execution logic of the function $\textit{dfs}$ is as follows: + +1. Find the starting position $i$ of the first placeholder in the string $\textit{s}$. If not found, return $\textit{s}$; +2. Find the ending position $j$ of the first placeholder in the string $\textit{s}$. If not found, return $\textit{s}$; +3. Extract the key of the placeholder, and then recursively replace the value of the placeholder $d[key]$; +4. Return the replaced string. + +In the main function, we call the $\textit{dfs}$ function, pass in the text string $\textit{text}$, and return the result. + +The time complexity is $O(m + n \times L)$, and the space complexity is $O(m + n \times L)$. Where $m$ is the length of the substitution mapping, and $n$ and $L$ are the length of the text string and the average length of the placeholders, respectively. #### Python3 ```python - +class Solution: + def applySubstitutions(self, replacements: List[List[str]], text: str) -> str: + def dfs(s: str) -> str: + i = s.find("%") + if i == -1: + return s + j = s.find("%", i + 1) + if j == -1: + return s + key = s[i + 1 : j] + replacement = dfs(d[key]) + return s[:i] + replacement + dfs(s[j + 1 :]) + + d = {s: t for s, t in replacements} + return dfs(text) ``` #### Java ```java - +class Solution { + private final Map d = new HashMap<>(); + + public String applySubstitutions(List> replacements, String text) { + for (List e : replacements) { + d.put(e.get(0), e.get(1)); + } + return dfs(text); + } + + private String dfs(String s) { + int i = s.indexOf("%"); + if (i == -1) { + return s; + } + int j = s.indexOf("%", i + 1); + if (j == -1) { + return s; + } + String key = s.substring(i + 1, j); + String replacement = dfs(d.getOrDefault(key, "")); + return s.substring(0, i) + replacement + dfs(s.substring(j + 1)); + } +} ``` #### C++ ```cpp - +class Solution { +public: + string applySubstitutions(vector>& replacements, string text) { + unordered_map d; + for (const auto& e : replacements) { + d[e[0]] = e[1]; + } + auto dfs = [&](this auto&& dfs, const string& s) -> string { + size_t i = s.find('%'); + if (i == string::npos) { + return s; + } + size_t j = s.find('%', i + 1); + if (j == string::npos) { + return s; + } + string key = s.substr(i + 1, j - i - 1); + string replacement = dfs(d[key]); + return s.substr(0, i) + replacement + dfs(s.substr(j + 1)); + }; + return dfs(text); + } +}; ``` #### Go ```go +func applySubstitutions(replacements [][]string, text string) string { + d := make(map[string]string) + for _, e := range replacements { + d[e[0]] = e[1] + } + var dfs func(string) string + dfs = func(s string) string { + i := strings.Index(s, "%") + if i == -1 { + return s + } + j := strings.Index(s[i+1:], "%") + if j == -1 { + return s + } + j += i + 1 + key := s[i+1 : j] + replacement := dfs(d[key]) + return s[:i] + replacement + dfs(s[j+1:]) + } + + return dfs(text) +} +``` +#### TypeScript + +```ts +function applySubstitutions(replacements: string[][], text: string): string { + const d: Record = {}; + for (const [key, value] of replacements) { + d[key] = value; + } + + const dfs = (s: string): string => { + const i = s.indexOf('%'); + if (i === -1) { + return s; + } + const j = s.indexOf('%', i + 1); + if (j === -1) { + return s; + } + const key = s.slice(i + 1, j); + const replacement = dfs(d[key] ?? ''); + return s.slice(0, i) + replacement + dfs(s.slice(j + 1)); + }; + + return dfs(text); +} ``` diff --git a/solution/3400-3499/3481.Apply Substitutions/Solution.cpp b/solution/3400-3499/3481.Apply Substitutions/Solution.cpp new file mode 100644 index 0000000000000..04890a99ca3fe --- /dev/null +++ b/solution/3400-3499/3481.Apply Substitutions/Solution.cpp @@ -0,0 +1,23 @@ +class Solution { +public: + string applySubstitutions(vector>& replacements, string text) { + unordered_map d; + for (const auto& e : replacements) { + d[e[0]] = e[1]; + } + auto dfs = [&](this auto&& dfs, const string& s) -> string { + size_t i = s.find('%'); + if (i == string::npos) { + return s; + } + size_t j = s.find('%', i + 1); + if (j == string::npos) { + return s; + } + string key = s.substr(i + 1, j - i - 1); + string replacement = dfs(d[key]); + return s.substr(0, i) + replacement + dfs(s.substr(j + 1)); + }; + return dfs(text); + } +}; diff --git a/solution/3400-3499/3481.Apply Substitutions/Solution.go b/solution/3400-3499/3481.Apply Substitutions/Solution.go new file mode 100644 index 0000000000000..ebba3ec2d9b23 --- /dev/null +++ b/solution/3400-3499/3481.Apply Substitutions/Solution.go @@ -0,0 +1,23 @@ +func applySubstitutions(replacements [][]string, text string) string { + d := make(map[string]string) + for _, e := range replacements { + d[e[0]] = e[1] + } + var dfs func(string) string + dfs = func(s string) string { + i := strings.Index(s, "%") + if i == -1 { + return s + } + j := strings.Index(s[i+1:], "%") + if j == -1 { + return s + } + j += i + 1 + key := s[i+1 : j] + replacement := dfs(d[key]) + return s[:i] + replacement + dfs(s[j+1:]) + } + + return dfs(text) +} diff --git a/solution/3400-3499/3481.Apply Substitutions/Solution.java b/solution/3400-3499/3481.Apply Substitutions/Solution.java new file mode 100644 index 0000000000000..1fbf3bc16df69 --- /dev/null +++ b/solution/3400-3499/3481.Apply Substitutions/Solution.java @@ -0,0 +1,24 @@ +class Solution { + private final Map d = new HashMap<>(); + + public String applySubstitutions(List> replacements, String text) { + for (List e : replacements) { + d.put(e.get(0), e.get(1)); + } + return dfs(text); + } + + private String dfs(String s) { + int i = s.indexOf("%"); + if (i == -1) { + return s; + } + int j = s.indexOf("%", i + 1); + if (j == -1) { + return s; + } + String key = s.substring(i + 1, j); + String replacement = dfs(d.getOrDefault(key, "")); + return s.substring(0, i) + replacement + dfs(s.substring(j + 1)); + } +} diff --git a/solution/3400-3499/3481.Apply Substitutions/Solution.py b/solution/3400-3499/3481.Apply Substitutions/Solution.py new file mode 100644 index 0000000000000..b3a32c63a191c --- /dev/null +++ b/solution/3400-3499/3481.Apply Substitutions/Solution.py @@ -0,0 +1,15 @@ +class Solution: + def applySubstitutions(self, replacements: List[List[str]], text: str) -> str: + def dfs(s: str) -> str: + i = s.find("%") + if i == -1: + return s + j = s.find("%", i + 1) + if j == -1: + return s + key = s[i + 1 : j] + replacement = dfs(d[key]) + return s[:i] + replacement + dfs(s[j + 1 :]) + + d = {s: t for s, t in replacements} + return dfs(text) diff --git a/solution/3400-3499/3481.Apply Substitutions/Solution.ts b/solution/3400-3499/3481.Apply Substitutions/Solution.ts new file mode 100644 index 0000000000000..afed69b2cfa79 --- /dev/null +++ b/solution/3400-3499/3481.Apply Substitutions/Solution.ts @@ -0,0 +1,22 @@ +function applySubstitutions(replacements: string[][], text: string): string { + const d: Record = {}; + for (const [key, value] of replacements) { + d[key] = value; + } + + const dfs = (s: string): string => { + const i = s.indexOf('%'); + if (i === -1) { + return s; + } + const j = s.indexOf('%', i + 1); + if (j === -1) { + return s; + } + const key = s.slice(i + 1, j); + const replacement = dfs(d[key] ?? ''); + return s.slice(0, i) + replacement + dfs(s.slice(j + 1)); + }; + + return dfs(text); +}