Skip to content

Commit 7381ede

Browse files
authored
feat: add solutions to lc problem: No.2131 (#4428)
No.2131.Longest Palindrome by Concatenating Two Letter Words
1 parent 853735d commit 7381ede

File tree

4 files changed

+76
-9
lines changed

4 files changed

+76
-9
lines changed

solution/2100-2199/2131.Longest Palindrome by Concatenating Two Letter Words/README.md

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,17 @@ tags:
7373

7474
### 方法一:贪心 + 哈希表
7575

76-
我们先用哈希表 `cnt` 统计每个单词出现的次数。
76+
我们先用一个哈希表 $\textit{cnt}$ 统计每个单词出现的次数。
7777

78-
遍历 `cnt` 中的每个单词 $k$ 以及其出现次数 $v$:
78+
遍历 $\textit{cnt}$ 中的每个单词 $k$ 以及其出现次数 $v$:
7979

80-
如果 $k$ 中两个字母相同,那么我们可以将 $\left \lfloor \frac{v}{2} \right \rfloor \times 2$ 个 $k$ 连接到回文串的前后,此时如果 $k$ 还剩余一个,那么我们可以先记录到 $x$ 中。
80+
- 如果 $k$ 中两个字母相同,那么我们可以将 $\left \lfloor \frac{v}{2} \right \rfloor \times 2$ 个 $k$ 连接到回文串的前后,此时如果 $k$ 还剩余一个,那么我们可以先记录到 $x$ 中。
8181

82-
如果 $k$ 中两个字母不同,那么我们要找到一个单词 $k'$,使得 $k'$ 中的两个字母与 $k$ 相反,即 $k' = k[1] + k[0]$。如果 $k'$ 存在,那么我们可以将 $\min(v, cnt[k'])$ 个 $k$ 连接到回文串的前后。
82+
- 如果 $k$ 中两个字母不同,那么我们要找到一个单词 $k'$,使得 $k'$ 中的两个字母与 $k$ 相反,即 $k' = k[1] + k[0]$。如果 $k'$ 存在,那么我们可以将 $\min(v, \textit{cnt}[k'])$ 个 $k$ 连接到回文串的前后。
8383

8484
遍历结束后,如果 $x$ 不为空,那么我们还可以将一个单词连接到回文串的中间。
8585

86-
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ `words` 的长度
86+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为单词的数量
8787

8888
<!-- tabs:start -->
8989

@@ -111,7 +111,7 @@ class Solution {
111111
public int longestPalindrome(String[] words) {
112112
Map<String, Integer> cnt = new HashMap<>();
113113
for (var w : words) {
114-
cnt.put(w, cnt.getOrDefault(w, 0) + 1);
114+
cnt.merge(w, 1, Integer::sum);
115115
}
116116
int ans = 0, x = 0;
117117
for (var e : cnt.entrySet()) {
@@ -183,6 +183,26 @@ func longestPalindrome(words []string) int {
183183
}
184184
```
185185

186+
#### TypeScript
187+
188+
```ts
189+
function longestPalindrome(words: string[]): number {
190+
const cnt = new Map<string, number>();
191+
for (const w of words) cnt.set(w, (cnt.get(w) || 0) + 1);
192+
let [ans, x] = [0, 0];
193+
for (const [k, v] of cnt.entries()) {
194+
if (k[0] === k[1]) {
195+
x += v & 1;
196+
ans += Math.floor(v / 2) * 2 * 2;
197+
} else {
198+
ans += Math.min(v, cnt.get(k[1] + k[0]) || 0) * 2;
199+
}
200+
}
201+
ans += x ? 2 : 0;
202+
return ans;
203+
}
204+
```
205+
186206
<!-- tabs:end -->
187207

188208
<!-- solution:end -->

solution/2100-2199/2131.Longest Palindrome by Concatenating Two Letter Words/README_EN.md

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,19 @@ Note that &quot;ll&quot; is another longest palindrome that can be created, and
7373

7474
<!-- solution:start -->
7575

76-
### Solution 1
76+
### Solution 1: Greedy + Hash Table
77+
78+
First, we use a hash table $\textit{cnt}$ to count the occurrences of each word.
79+
80+
Iterate through each word $k$ and its count $v$ in $\textit{cnt}$:
81+
82+
- If the two letters in $k$ are the same, we can concatenate $\left \lfloor \frac{v}{2} \right \rfloor \times 2$ copies of $k$ to the front and back of the palindrome. If there is one $k$ left, we can record it in $x$ for now.
83+
84+
- If the two letters in $k$ are different, we need to find a word $k'$ such that the two letters in $k'$ are the reverse of $k$, i.e., $k' = k[1] + k[0]$. If $k'$ exists, we can concatenate $\min(v, \textit{cnt}[k'])$ copies of $k$ to the front and back of the palindrome.
85+
86+
After the iteration, if $x$ is not empty, we can also place one word in the middle of the palindrome.
87+
88+
The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the number of words.
7789

7890
<!-- tabs:start -->
7991

@@ -101,7 +113,7 @@ class Solution {
101113
public int longestPalindrome(String[] words) {
102114
Map<String, Integer> cnt = new HashMap<>();
103115
for (var w : words) {
104-
cnt.put(w, cnt.getOrDefault(w, 0) + 1);
116+
cnt.merge(w, 1, Integer::sum);
105117
}
106118
int ans = 0, x = 0;
107119
for (var e : cnt.entrySet()) {
@@ -173,6 +185,26 @@ func longestPalindrome(words []string) int {
173185
}
174186
```
175187

188+
#### TypeScript
189+
190+
```ts
191+
function longestPalindrome(words: string[]): number {
192+
const cnt = new Map<string, number>();
193+
for (const w of words) cnt.set(w, (cnt.get(w) || 0) + 1);
194+
let [ans, x] = [0, 0];
195+
for (const [k, v] of cnt.entries()) {
196+
if (k[0] === k[1]) {
197+
x += v & 1;
198+
ans += Math.floor(v / 2) * 2 * 2;
199+
} else {
200+
ans += Math.min(v, cnt.get(k[1] + k[0]) || 0) * 2;
201+
}
202+
}
203+
ans += x ? 2 : 0;
204+
return ans;
205+
}
206+
```
207+
176208
<!-- tabs:end -->
177209

178210
<!-- solution:end -->

solution/2100-2199/2131.Longest Palindrome by Concatenating Two Letter Words/Solution.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ class Solution {
22
public int longestPalindrome(String[] words) {
33
Map<String, Integer> cnt = new HashMap<>();
44
for (var w : words) {
5-
cnt.put(w, cnt.getOrDefault(w, 0) + 1);
5+
cnt.merge(w, 1, Integer::sum);
66
}
77
int ans = 0, x = 0;
88
for (var e : cnt.entrySet()) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function longestPalindrome(words: string[]): number {
2+
const cnt = new Map<string, number>();
3+
for (const w of words) cnt.set(w, (cnt.get(w) || 0) + 1);
4+
let [ans, x] = [0, 0];
5+
for (const [k, v] of cnt.entries()) {
6+
if (k[0] === k[1]) {
7+
x += v & 1;
8+
ans += Math.floor(v / 2) * 2 * 2;
9+
} else {
10+
ans += Math.min(v, cnt.get(k[1] + k[0]) || 0) * 2;
11+
}
12+
}
13+
ans += x ? 2 : 0;
14+
return ans;
15+
}

0 commit comments

Comments
 (0)