Skip to content

Commit 19db0e7

Browse files
committed
update: 添加问题“2131.连接两字母单词得到的最长回文串”的代码和题解(#955)
Signed-off-by: LetMeFly666 <[email protected]>
1 parent 8541171 commit 19db0e7

13 files changed

+756
-3
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* @Author: LetMeFly
3+
* @Date: 2025-05-25 23:39:17
4+
* @LastEditors: LetMeFly.xyz
5+
* @LastEditTime: 2025-05-26 00:04:19
6+
*/
7+
#if defined(_WIN32) || defined(__APPLE__)
8+
#include "_[1,2]toVector.h"
9+
#endif
10+
11+
class Solution {
12+
public:
13+
int longestPalindrome(vector<string>& words) {
14+
int cnt[26][26] = {0};
15+
for (string& word : words) {
16+
cnt[word[0] - 'a'][word[1] - 'a']++;
17+
}
18+
int ans = 0, middle = 0;
19+
for (int i = 0; i < 26; i++) {
20+
ans += cnt[i][i] / 2 * 2;
21+
middle |= cnt[i][i] % 2;
22+
for (int j = i + 1; j < 26; j++) {
23+
ans += min(cnt[i][j], cnt[j][i]) * 2;
24+
}
25+
}
26+
return (ans + middle) * 2;
27+
}
28+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* @Author: LetMeFly
3+
* @Date: 2025-05-25 23:39:17
4+
* @LastEditors: LetMeFly.xyz
5+
* @LastEditTime: 2025-05-25 23:54:22
6+
*/
7+
package main
8+
9+
func longestPalindrome(words []string) int {
10+
times := make([][]int, 26)
11+
for i := range times {
12+
times[i] = make([]int, 26)
13+
}
14+
for _, word := range words {
15+
times[word[0] - 'a'][word[1] - 'a']++
16+
}
17+
side, mid := 0, 0
18+
for i := range times {
19+
side += times[i][i] / 2 * 2
20+
mid |= times[i][i] % 2
21+
for j := i + 1; j < 26; j++ {
22+
side += min(times[i][j], times[j][i]) * 2
23+
}
24+
}
25+
return (side + mid) * 2
26+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* @Author: LetMeFly
3+
* @Date: 2025-05-25 23:39:17
4+
* @LastEditors: LetMeFly.xyz
5+
* @LastEditTime: 2025-05-25 23:51:33
6+
*/
7+
class Solution {
8+
public int longestPalindrome(String[] words) {
9+
int[][] times = new int[26][26];
10+
for (String word : words) {
11+
times[word.charAt(0) - 'a'][word.charAt(1) - 'a']++;
12+
}
13+
int side = 0, middle = 0;
14+
for (int i = 0; i < 26; i++) {
15+
side += times[i][i] / 2 * 2;
16+
middle |= times[i][i] % 2;
17+
for (int j = i + 1; j < 26; j++) {
18+
side += Math.min(times[i][j], times[j][i]) * 2;
19+
}
20+
}
21+
return (side + middle) * 2;
22+
}
23+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'''
2+
Author: LetMeFly
3+
Date: 2025-05-25 23:39:17
4+
LastEditors: LetMeFly.xyz
5+
LastEditTime: 2025-05-25 23:47:11
6+
'''
7+
from typing import List
8+
9+
class Solution:
10+
def longestPalindrome(self, words: List[str]) -> int:
11+
cnt = [[0] * 26 for _ in range(26)]
12+
for word in words:
13+
cnt[ord(word[0]) - ord('a')][ord(word[1]) - ord('a')] += 1
14+
ans = middle = 0
15+
for i in range(26):
16+
ans += cnt[i][i] // 2 * 2
17+
middle |= cnt[i][i] % 2
18+
for j in range(i + 1, 26):
19+
ans += min(cnt[i][j], cnt[j][i]) * 2
20+
return (ans + middle) * 2

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,7 @@
676676
|2109.向字符串添加空格|中等|<a href="https://leetcode.cn/problems/adding-spaces-to-a-string/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2025/03/31/LeetCode%202109.%E5%90%91%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%B7%BB%E5%8A%A0%E7%A9%BA%E6%A0%BC/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/146863199" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/adding-spaces-to-a-string/solutions/3635218/letmefly-2109xiang-zi-fu-chuan-tian-jia-cectp/" target="_blank">LeetCode题解</a>|
677677
|2116.判断一个括号字符串是否有效|中等|<a href="https://leetcode.cn/problems/check-if-a-parentheses-string-can-be-valid/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2025/03/23/LeetCode%202116.%E5%88%A4%E6%96%AD%E4%B8%80%E4%B8%AA%E6%8B%AC%E5%8F%B7%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%98%AF%E5%90%A6%E6%9C%89%E6%95%88/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/146454056" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/check-if-a-parentheses-string-can-be-valid/solutions/3624225/letmefly-2116pan-duan-yi-ge-gua-hao-zi-f-9n2z/" target="_blank">LeetCode题解</a>|
678678
|2129.将标题首字母大写|简单|<a href="https://leetcode.cn/problems/capitalize-the-title/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2024/03/11/LeetCode%202129.%E5%B0%86%E6%A0%87%E9%A2%98%E9%A6%96%E5%AD%97%E6%AF%8D%E5%A4%A7%E5%86%99/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/136614914" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/capitalize-the-title/solutions/2679708/letmefly-2129jiang-biao-ti-shou-zi-mu-da-nj90/" target="_blank">LeetCode题解</a>|
679+
|2131.连接两字母单词得到的最长回文串|中等|<a href="https://leetcode.cn/problems/longest-palindrome-by-concatenating-two-letter-words/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2025/05/25/LeetCode%202131.%E8%BF%9E%E6%8E%A5%E4%B8%A4%E5%AD%97%E6%AF%8D%E5%8D%95%E8%AF%8D%E5%BE%97%E5%88%B0%E7%9A%84%E6%9C%80%E9%95%BF%E5%9B%9E%E6%96%87%E4%B8%B2/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/148216376" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/longest-palindrome-by-concatenating-two-letter-words/solutions/3686003/letmefly-2131lian-jie-liang-zi-mu-dan-ci-h5i2/" target="_blank">LeetCode题解</a>|
679680
|2132.用邮票贴满网格图|困难|<a href="https://leetcode.cn/problems/stamping-the-grid/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2023/12/14/LeetCode%202132.%E7%94%A8%E9%82%AE%E7%A5%A8%E8%B4%B4%E6%BB%A1%E7%BD%91%E6%A0%BC%E5%9B%BE/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/135002925" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/stamping-the-grid/solutions/2566644/letmefly-2132yong-you-piao-tie-man-wang-znigh/" target="_blank">LeetCode题解</a>|
680681
|2140.解决智力问题|中等|<a href="https://leetcode.cn/problems/solving-questions-with-brainpower/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2025/04/03/LeetCode%202140.%E8%A7%A3%E5%86%B3%E6%99%BA%E5%8A%9B%E9%97%AE%E9%A2%98/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/146991317" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/solving-questions-with-brainpower/solutions/3639601/letmefly-2140jie-jue-zhi-li-wen-ti-ji-yi-pxc4/" target="_blank">LeetCode题解</a>|
681682
|2171.拿出最少数目的魔法豆|中等|<a href="https://leetcode.cn/problems/removing-minimum-number-of-magic-beans/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2024/01/18/LeetCode%202171.%E6%8B%BF%E5%87%BA%E6%9C%80%E5%B0%91%E6%95%B0%E7%9B%AE%E7%9A%84%E9%AD%94%E6%B3%95%E8%B1%86/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/135682601" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/removing-minimum-number-of-magic-beans/solutions/2609831/letmefly-2171na-chu-zui-shao-shu-mu-de-m-jima/" target="_blank">LeetCode题解</a>|
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
---
2+
title: 2131.连接两字母单词得到的最长回文串:分类讨论(贪心)
3+
date: 2025-05-25 23:56:17
4+
tags: [题解, LeetCode, 中等, 贪心, 数组, 哈希表, 字符串, 计数, 回文, 回文串]
5+
categories: [题解, LeetCode]
6+
---
7+
8+
# 【LetMeFly】2131.连接两字母单词得到的最长回文串:分类讨论(贪心)
9+
10+
力扣题目链接:[https://leetcode.cn/problems/longest-palindrome-by-concatenating-two-letter-words/](https://leetcode.cn/problems/longest-palindrome-by-concatenating-two-letter-words/)
11+
12+
<p>给你一个字符串数组&nbsp;<code>words</code>&nbsp;。<code>words</code>&nbsp;中每个元素都是一个包含 <strong>两个</strong>&nbsp;小写英文字母的单词。</p>
13+
14+
<p>请你从 <code>words</code>&nbsp;中选择一些元素并按 <b>任意顺序</b>&nbsp;连接它们,并得到一个 <strong>尽可能长的回文串</strong>&nbsp;。每个元素 <strong>至多</strong>&nbsp;只能使用一次。</p>
15+
16+
<p>请你返回你能得到的最长回文串的 <strong>长度</strong>&nbsp;。如果没办法得到任何一个回文串,请你返回 <code>0</code>&nbsp;。</p>
17+
18+
<p><strong>回文串</strong>&nbsp;指的是从前往后和从后往前读一样的字符串。</p>
19+
20+
<p>&nbsp;</p>
21+
22+
<p><strong>示例 1:</strong></p>
23+
24+
<pre><b>输入:</b>words = ["lc","cl","gg"]
25+
<b>输出:</b>6
26+
<b>解释:</b>一个最长的回文串为 "lc" + "gg" + "cl" = "lcggcl" ,长度为 6 。
27+
"clgglc" 是另一个可以得到的最长回文串。
28+
</pre>
29+
30+
<p><strong>示例 2:</strong></p>
31+
32+
<pre><b>输入:</b>words = ["ab","ty","yt","lc","cl","ab"]
33+
<b>输出:</b>8
34+
<strong>解释:</strong>最长回文串是 "ty" + "lc" + "cl" + "yt" = "tylcclyt" ,长度为 8 。
35+
"lcyttycl" 是另一个可以得到的最长回文串。
36+
</pre>
37+
38+
<p><strong>示例 3:</strong></p>
39+
40+
<pre><b>输入:</b>words = ["cc","ll","xx"]
41+
<b>输出:</b>2
42+
<b>解释:</b>最长回文串是 "cc" ,长度为 2 。
43+
"ll" 是另一个可以得到的最长回文串。"xx" 也是。</pre>
44+
45+
<p>&nbsp;</p>
46+
47+
<p><strong>提示:</strong></p>
48+
49+
<ul>
50+
<li><code>1 &lt;= words.length &lt;= 10<sup>5</sup></code></li>
51+
<li><code>words[i].length == 2</code></li>
52+
<li><code>words[i]</code>&nbsp;仅包含小写英文字母。</li>
53+
</ul>
54+
55+
56+
57+
## 解题方法:分类讨论
58+
59+
### 解题思路
60+
61+
有的字符串自对称(如`aa`),有的字符串非自对称(如`ab`)。
62+
63+
非对称的字符串只能和和它对称的字符串放到对称的位置(如`ab**ba`),而自对称的字符串不但能和自身放到对称的位置(如`aa**aa`)也可以自身单独放到最中间的位置(如`**aa**`)。
64+
65+
但是,在整个最终构造的字符串中,自对称放字符串放到最中间的至多只能有一个。
66+
67+
### 具体方法
68+
69+
使用一个哈希表或`26x26`大小的数组统计每种字符串的出现次数。
70+
71+
使用变量`i``0``25`遍历:
72+
73+
> 首先对于自对称的字符串(如`aa`),假设有$n$个,则可以拿$\lfloor\frac{n}2\rfloor$对放到对称的位置。若$n$为奇数,则还可以保留一个放到最中间的位置。
74+
>
75+
> 接着使用变量`j``i+1``26`遍历,可以互相放到对称位置的字符串一共有$\min(times[i][j], times[j][i])$对。
76+
77+
最终,由于中间位置最多只能放一对,所以$(对称对数\times2+中间个数)\times 2$即为所求。
78+
79+
### 时空复杂度分析
80+
81+
+ 时间复杂度$O(N^2)$
82+
+ 空间复杂度$O(N\log N)$
83+
84+
### AC代码
85+
86+
#### Go
87+
88+
```go
89+
/*
90+
* @Author: LetMeFly
91+
* @Date: 2025-05-25 23:39:17
92+
* @LastEditors: LetMeFly.xyz
93+
* @LastEditTime: 2025-05-25 23:54:22
94+
*/
95+
package main
96+
97+
func longestPalindrome(words []string) int {
98+
times := make([][]int, 26)
99+
for i := range times {
100+
times[i] = make([]int, 26)
101+
}
102+
for _, word := range words {
103+
times[word[0] - 'a'][word[1] - 'a']++
104+
}
105+
side, mid := 0, 0
106+
for i := range times {
107+
side += times[i][i] / 2 * 2
108+
mid |= times[i][i] % 2
109+
for j := i + 1; j < 26; j++ {
110+
side += min(times[i][j], times[j][i]) * 2
111+
}
112+
}
113+
return (side + mid) * 2
114+
}
115+
```
116+
117+
#### C++
118+
119+
```cpp
120+
/*
121+
* @Author: LetMeFly
122+
* @Date: 2025-05-25 23:39:17
123+
* @LastEditors: LetMeFly.xyz
124+
* @LastEditTime: 2025-05-26 00:04:19
125+
*/
126+
class Solution {
127+
public:
128+
int longestPalindrome(vector<string>& words) {
129+
int cnt[26][26] = {0};
130+
for (string& word : words) {
131+
cnt[word[0] - 'a'][word[1] - 'a']++;
132+
}
133+
int ans = 0, middle = 0;
134+
for (int i = 0; i < 26; i++) {
135+
ans += cnt[i][i] / 2 * 2;
136+
middle |= cnt[i][i] % 2;
137+
for (int j = i + 1; j < 26; j++) {
138+
ans += min(cnt[i][j], cnt[j][i]) * 2;
139+
}
140+
}
141+
return (ans + middle) * 2;
142+
}
143+
};
144+
```
145+
146+
#### Python
147+
148+
```python
149+
'''
150+
Author: LetMeFly
151+
Date: 2025-05-25 23:39:17
152+
LastEditors: LetMeFly.xyz
153+
LastEditTime: 2025-05-25 23:47:11
154+
'''
155+
from typing import List
156+
157+
class Solution:
158+
def longestPalindrome(self, words: List[str]) -> int:
159+
cnt = [[0] * 26 for _ in range(26)]
160+
for word in words:
161+
cnt[ord(word[0]) - ord('a')][ord(word[1]) - ord('a')] += 1
162+
ans = middle = 0
163+
for i in range(26):
164+
ans += cnt[i][i] // 2 * 2
165+
middle |= cnt[i][i] % 2
166+
for j in range(i + 1, 26):
167+
ans += min(cnt[i][j], cnt[j][i]) * 2
168+
return (ans + middle) * 2
169+
```
170+
171+
#### Java
172+
173+
```java
174+
/*
175+
* @Author: LetMeFly
176+
* @Date: 2025-05-25 23:39:17
177+
* @LastEditors: LetMeFly.xyz
178+
* @LastEditTime: 2025-05-25 23:51:33
179+
*/
180+
class Solution {
181+
public int longestPalindrome(String[] words) {
182+
int[][] times = new int[26][26];
183+
for (String word : words) {
184+
times[word.charAt(0) - 'a'][word.charAt(1) - 'a']++;
185+
}
186+
int side = 0, middle = 0;
187+
for (int i = 0; i < 26; i++) {
188+
side += times[i][i] / 2 * 2;
189+
middle |= times[i][i] % 2;
190+
for (int j = i + 1; j < 26; j++) {
191+
side += Math.min(times[i][j], times[j][i]) * 2;
192+
}
193+
}
194+
return (side + middle) * 2;
195+
}
196+
}
197+
```
198+
199+
> 同步发文于[CSDN](https://letmefly.blog.csdn.net/article/details/148216376)和我的[个人博客](https://blog.letmefly.xyz/),原创不易,转载经作者同意后请附上[原文链接](https://blog.letmefly.xyz/2025/05/25/LeetCode%202131.%E8%BF%9E%E6%8E%A5%E4%B8%A4%E5%AD%97%E6%AF%8D%E5%8D%95%E8%AF%8D%E5%BE%97%E5%88%B0%E7%9A%84%E6%9C%80%E9%95%BF%E5%9B%9E%E6%96%87%E4%B8%B2/)哦~
200+
>
201+
> 千篇源码题解[已开源](https://github.com/LetMeFly666/LeetCode)
202+
203+
(最近CSDN发文时咋不出默认封面图了)

Solutions/Other-English-LearningNotes-SomeWords.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,10 @@ categories: [自用]
11831183
|stipulate|v. 规定,明确要求<br/>adj. 有托叶的|
11841184
|businesslike|adj. 高效的,井然有序的,工作认真而有条理的|
11851185
|buddhism|n. 佛教|
1186+
|||
1187+
|arduous|adj. 艰苦的,简单的,费力的|
1188+
|wherein|adv. 其中,在那里,在那种情况下,以什么方式<details><summary>例句</summary>He looked around the room, <font color="#28bea0">wherein</font> were assembled his entire family.<br/>他环视了下房间,他全家人都在那里。</details>|
1189+
|handout|n. 捐赠品,救济品,传单,(发给学生的)课堂讲义|
11861190

11871191
<p class="wordCounts">单词收录总数</p>
11881192

Solutions/Other-Japanese-LearningNotes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ xx型
358358
|静か(しずか)|安静的|
359359
|にぎやか|热闹的|
360360
|いろいろ|各种各样的|
361+
|カラフル(colorful)|五颜六色的|
361362
|じょうぶ|结实的|
362363
|明るい(あかるい)|明亮的|
363364
|暗い(くらい)|昏暗的|
@@ -403,6 +404,7 @@ xx型
403404
|窓(まど)|窗户|
404405
|カーテン|窗帘|
405406
|ゆか|地板|
407+
|カーペット|地毯|
406408
|冷蔵庫(れいぞうこ)|冰箱|
407409
|ソファ(sofa)|沙发|
408410
|家具(かぐ)|家具|
@@ -503,6 +505,7 @@ xx型
503505
|ゴミ|垃圾|
504506
|広告(こうこく)|广告|
505507
|シャンプー|洗发水|
508+
|アクセサリー(accessory)|配件|
506509
|||
507510
|シャツ|衬衫|
508511
|Tシャツ|T恤|
@@ -541,6 +544,7 @@ xx型
541544
|レストラン|餐馆|
542545
|ダイニング|餐厅|
543546
|食堂(しょくどう)|食堂|
547+
|会場(かいじょう)|会场|
544548
|カフェ|咖啡馆|
545549
|コンビニ|便利店|
546550
|図書館(としょかん)|图书馆|

toSay.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!--
2+
* @Author: LetMeFly
3+
* @Date: 2025-05-25 22:00:40
4+
* @LastEditors: LetMeFly.xyz
5+
* @LastEditTime: 2025-05-25 22:00:57
6+
-->
7+
愉快周末又要结束了
8+
9+
周日下午一个组会直接干掉大半天

tryGoPy/MGJW/thisWeek/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pics

0 commit comments

Comments
 (0)