From cc4815a3e4d5dd643bcab0636017eb88ad86a31f Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Mon, 6 Jan 2025 11:34:39 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.3412 (#3930) No.3412.Find Mirror Score of a String --- .../README.md | 114 +++++++++++++++++- .../README_EN.md | 114 +++++++++++++++++- .../Solution.cpp | 24 ++++ .../Solution.go | 17 +++ .../Solution.java | 22 ++++ .../Solution.py | 12 ++ .../Solution.ts | 24 ++++ 7 files changed, 319 insertions(+), 8 deletions(-) create mode 100644 solution/3400-3499/3412.Find Mirror Score of a String/Solution.cpp create mode 100644 solution/3400-3499/3412.Find Mirror Score of a String/Solution.go create mode 100644 solution/3400-3499/3412.Find Mirror Score of a String/Solution.java create mode 100644 solution/3400-3499/3412.Find Mirror Score of a String/Solution.py create mode 100644 solution/3400-3499/3412.Find Mirror Score of a String/Solution.ts diff --git a/solution/3400-3499/3412.Find Mirror Score of a String/README.md b/solution/3400-3499/3412.Find Mirror Score of a String/README.md index 34a82eb991320..5676acca22380 100644 --- a/solution/3400-3499/3412.Find Mirror Score of a String/README.md +++ b/solution/3400-3499/3412.Find Mirror Score of a String/README.md @@ -77,32 +77,138 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3412.Fi -### 方法一 +### 方法一:哈希表 + +我们可以用一个哈希表 $\textit{d}$ 来存储每个未标记的字符的下标列表,其中键是字符,值是下标列表。 + +我们遍历字符串 $\textit{s}$,对于每个字符 $\textit{x}$,我们找到其镜像字符 $\textit{y}$,如果 $\textit{d}$ 中存在 $\textit{y}$,我们就取出 $\textit{y}$ 对应的下标列表 $\textit{ls}$,取出 $\textit{ls}$ 的最后一个元素 $\textit{j}$,并将 $\textit{j}$ 从 $\textit{ls}$ 中移除。如果 $\textit{ls}$ 变为空,我们就将 $\textit{y}$ 从 $\textit{d}$ 中移除。此时,我们就找到了一个满足条件的下标对 $(\textit{j}, \textit{i})$,并将 $\textit{i} - \textit{j}$ 加到答案中。否则,我们将 $\textit{x}$ 加入到 $\textit{d}$ 中。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $\textit{s}$ 的长度。 #### Python3 ```python - +class Solution: + def calculateScore(self, s: str) -> int: + d = defaultdict(list) + ans = 0 + for i, x in enumerate(s): + y = chr(ord("a") + ord("z") - ord(x)) + if d[y]: + j = d[y].pop() + ans += i - j + else: + d[x].append(i) + return ans ``` #### Java ```java - +class Solution { + public long calculateScore(String s) { + Map> d = new HashMap<>(26); + int n = s.length(); + long ans = 0; + for (int i = 0; i < n; ++i) { + char x = s.charAt(i); + char y = (char) ('a' + 'z' - x); + if (d.containsKey(y)) { + var ls = d.get(y); + int j = ls.remove(ls.size() - 1); + if (ls.isEmpty()) { + d.remove(y); + } + ans += i - j; + } else { + d.computeIfAbsent(x, k -> new ArrayList<>()).add(i); + } + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + long long calculateScore(string s) { + unordered_map> d; + int n = s.length(); + long long ans = 0; + for (int i = 0; i < n; ++i) { + char x = s[i]; + char y = 'a' + 'z' - x; + if (d.contains(y)) { + vector& ls = d[y]; + int j = ls.back(); + ls.pop_back(); + if (ls.empty()) { + d.erase(y); + } + ans += i - j; + } else { + d[x].push_back(i); + } + } + return ans; + } +}; ``` #### Go ```go +func calculateScore(s string) (ans int64) { + d := make(map[rune][]int) + for i, x := range s { + y := 'a' + 'z' - x + if ls, ok := d[y]; ok { + j := ls[len(ls)-1] + d[y] = ls[:len(ls)-1] + if len(d[y]) == 0 { + delete(d, y) + } + ans += int64(i - j) + } else { + d[x] = append(d[x], i) + } + } + return +} +``` +#### TypeScript + +```ts +function calculateScore(s: string): number { + const d: Map = new Map(); + const n = s.length; + let ans = 0; + for (let i = 0; i < n; i++) { + const x = s[i]; + const y = String.fromCharCode('a'.charCodeAt(0) + 'z'.charCodeAt(0) - x.charCodeAt(0)); + + if (d.has(y)) { + const ls = d.get(y)!; + const j = ls.pop()!; + if (ls.length === 0) { + d.delete(y); + } + ans += i - j; + } else { + if (!d.has(x)) { + d.set(x, []); + } + d.get(x)!.push(i); + } + } + return ans; +} ``` diff --git a/solution/3400-3499/3412.Find Mirror Score of a String/README_EN.md b/solution/3400-3499/3412.Find Mirror Score of a String/README_EN.md index 2f4894710d65c..380054b928b20 100644 --- a/solution/3400-3499/3412.Find Mirror Score of a String/README_EN.md +++ b/solution/3400-3499/3412.Find Mirror Score of a String/README_EN.md @@ -75,32 +75,138 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3412.Fi -### Solution 1 +### Solution 1: Hash Table + +We can use a hash table $\textit{d}$ to store the index list of each unmarked character, where the key is the character and the value is the list of indices. + +We traverse the string $\textit{s}$, and for each character $\textit{x}$, we find its mirror character $\textit{y}$. If $\textit{d}$ contains $\textit{y}$, we take out the index list $\textit{ls}$ corresponding to $\textit{y}$, take out the last element $\textit{j}$ from $\textit{ls}$, and remove $\textit{j}$ from $\textit{ls}$. If $\textit{ls}$ becomes empty, we remove $\textit{y}$ from $\textit{d}$. At this point, we have found a pair of indices $(\textit{j}, \textit{i})$ that meet the condition, and we add $\textit{i} - \textit{j}$ to the answer. Otherwise, we add $\textit{x}$ to $\textit{d}$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string $\textit{s}$. #### Python3 ```python - +class Solution: + def calculateScore(self, s: str) -> int: + d = defaultdict(list) + ans = 0 + for i, x in enumerate(s): + y = chr(ord("a") + ord("z") - ord(x)) + if d[y]: + j = d[y].pop() + ans += i - j + else: + d[x].append(i) + return ans ``` #### Java ```java - +class Solution { + public long calculateScore(String s) { + Map> d = new HashMap<>(26); + int n = s.length(); + long ans = 0; + for (int i = 0; i < n; ++i) { + char x = s.charAt(i); + char y = (char) ('a' + 'z' - x); + if (d.containsKey(y)) { + var ls = d.get(y); + int j = ls.remove(ls.size() - 1); + if (ls.isEmpty()) { + d.remove(y); + } + ans += i - j; + } else { + d.computeIfAbsent(x, k -> new ArrayList<>()).add(i); + } + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + long long calculateScore(string s) { + unordered_map> d; + int n = s.length(); + long long ans = 0; + for (int i = 0; i < n; ++i) { + char x = s[i]; + char y = 'a' + 'z' - x; + if (d.contains(y)) { + vector& ls = d[y]; + int j = ls.back(); + ls.pop_back(); + if (ls.empty()) { + d.erase(y); + } + ans += i - j; + } else { + d[x].push_back(i); + } + } + return ans; + } +}; ``` #### Go ```go +func calculateScore(s string) (ans int64) { + d := make(map[rune][]int) + for i, x := range s { + y := 'a' + 'z' - x + if ls, ok := d[y]; ok { + j := ls[len(ls)-1] + d[y] = ls[:len(ls)-1] + if len(d[y]) == 0 { + delete(d, y) + } + ans += int64(i - j) + } else { + d[x] = append(d[x], i) + } + } + return +} +``` +#### TypeScript + +```ts +function calculateScore(s: string): number { + const d: Map = new Map(); + const n = s.length; + let ans = 0; + for (let i = 0; i < n; i++) { + const x = s[i]; + const y = String.fromCharCode('a'.charCodeAt(0) + 'z'.charCodeAt(0) - x.charCodeAt(0)); + + if (d.has(y)) { + const ls = d.get(y)!; + const j = ls.pop()!; + if (ls.length === 0) { + d.delete(y); + } + ans += i - j; + } else { + if (!d.has(x)) { + d.set(x, []); + } + d.get(x)!.push(i); + } + } + return ans; +} ``` diff --git a/solution/3400-3499/3412.Find Mirror Score of a String/Solution.cpp b/solution/3400-3499/3412.Find Mirror Score of a String/Solution.cpp new file mode 100644 index 0000000000000..2f33685a1be2b --- /dev/null +++ b/solution/3400-3499/3412.Find Mirror Score of a String/Solution.cpp @@ -0,0 +1,24 @@ +class Solution { +public: + long long calculateScore(string s) { + unordered_map> d; + int n = s.length(); + long long ans = 0; + for (int i = 0; i < n; ++i) { + char x = s[i]; + char y = 'a' + 'z' - x; + if (d.contains(y)) { + vector& ls = d[y]; + int j = ls.back(); + ls.pop_back(); + if (ls.empty()) { + d.erase(y); + } + ans += i - j; + } else { + d[x].push_back(i); + } + } + return ans; + } +}; diff --git a/solution/3400-3499/3412.Find Mirror Score of a String/Solution.go b/solution/3400-3499/3412.Find Mirror Score of a String/Solution.go new file mode 100644 index 0000000000000..347ecdcf6dd51 --- /dev/null +++ b/solution/3400-3499/3412.Find Mirror Score of a String/Solution.go @@ -0,0 +1,17 @@ +func calculateScore(s string) (ans int64) { + d := make(map[rune][]int) + for i, x := range s { + y := 'a' + 'z' - x + if ls, ok := d[y]; ok { + j := ls[len(ls)-1] + d[y] = ls[:len(ls)-1] + if len(d[y]) == 0 { + delete(d, y) + } + ans += int64(i - j) + } else { + d[x] = append(d[x], i) + } + } + return +} diff --git a/solution/3400-3499/3412.Find Mirror Score of a String/Solution.java b/solution/3400-3499/3412.Find Mirror Score of a String/Solution.java new file mode 100644 index 0000000000000..8704bd6c7b980 --- /dev/null +++ b/solution/3400-3499/3412.Find Mirror Score of a String/Solution.java @@ -0,0 +1,22 @@ +class Solution { + public long calculateScore(String s) { + Map> d = new HashMap<>(26); + int n = s.length(); + long ans = 0; + for (int i = 0; i < n; ++i) { + char x = s.charAt(i); + char y = (char) ('a' + 'z' - x); + if (d.containsKey(y)) { + var ls = d.get(y); + int j = ls.remove(ls.size() - 1); + if (ls.isEmpty()) { + d.remove(y); + } + ans += i - j; + } else { + d.computeIfAbsent(x, k -> new ArrayList<>()).add(i); + } + } + return ans; + } +} diff --git a/solution/3400-3499/3412.Find Mirror Score of a String/Solution.py b/solution/3400-3499/3412.Find Mirror Score of a String/Solution.py new file mode 100644 index 0000000000000..26a86e7dfeda1 --- /dev/null +++ b/solution/3400-3499/3412.Find Mirror Score of a String/Solution.py @@ -0,0 +1,12 @@ +class Solution: + def calculateScore(self, s: str) -> int: + d = defaultdict(list) + ans = 0 + for i, x in enumerate(s): + y = chr(ord("a") + ord("z") - ord(x)) + if d[y]: + j = d[y].pop() + ans += i - j + else: + d[x].append(i) + return ans diff --git a/solution/3400-3499/3412.Find Mirror Score of a String/Solution.ts b/solution/3400-3499/3412.Find Mirror Score of a String/Solution.ts new file mode 100644 index 0000000000000..25168292d6ddf --- /dev/null +++ b/solution/3400-3499/3412.Find Mirror Score of a String/Solution.ts @@ -0,0 +1,24 @@ +function calculateScore(s: string): number { + const d: Map = new Map(); + const n = s.length; + let ans = 0; + for (let i = 0; i < n; i++) { + const x = s[i]; + const y = String.fromCharCode('a'.charCodeAt(0) + 'z'.charCodeAt(0) - x.charCodeAt(0)); + + if (d.has(y)) { + const ls = d.get(y)!; + const j = ls.pop()!; + if (ls.length === 0) { + d.delete(y); + } + ans += i - j; + } else { + if (!d.has(x)) { + d.set(x, []); + } + d.get(x)!.push(i); + } + } + return ans; +}