comments | difficulty | edit_url | rating | source | tags | |||||
---|---|---|---|---|---|---|---|---|---|---|
true |
中等 |
1556 |
第 69 场双周赛 Q3 |
|
给你一个字符串数组 words
。words
中每个元素都是一个包含 两个 小写英文字母的单词。
请你从 words
中选择一些元素并按 任意顺序 连接它们,并得到一个 尽可能长的回文串 。每个元素 至多 只能使用一次。
请你返回你能得到的最长回文串的 长度 。如果没办法得到任何一个回文串,请你返回 0
。
回文串 指的是从前往后和从后往前读一样的字符串。
示例 1:
输入:words = ["lc","cl","gg"] 输出:6 解释:一个最长的回文串为 "lc" + "gg" + "cl" = "lcggcl" ,长度为 6 。 "clgglc" 是另一个可以得到的最长回文串。
示例 2:
输入:words = ["ab","ty","yt","lc","cl","ab"] 输出:8 解释:最长回文串是 "ty" + "lc" + "cl" + "yt" = "tylcclyt" ,长度为 8 。 "lcyttycl" 是另一个可以得到的最长回文串。
示例 3:
输入:words = ["cc","ll","xx"] 输出:2 解释:最长回文串是 "cc" ,长度为 2 。 "ll" 是另一个可以得到的最长回文串。"xx" 也是。
提示:
1 <= words.length <= 105
words[i].length == 2
words[i]
仅包含小写英文字母。
我们先用哈希表 cnt
统计每个单词出现的次数。
遍历 cnt
中的每个单词
如果
如果
遍历结束后,如果
时间复杂度 words
的长度。
class Solution:
def longestPalindrome(self, words: List[str]) -> int:
cnt = Counter(words)
ans = x = 0
for k, v in cnt.items():
if k[0] == k[1]:
x += v & 1
ans += v // 2 * 2 * 2
else:
ans += min(v, cnt[k[::-1]]) * 2
ans += 2 if x else 0
return ans
class Solution {
public int longestPalindrome(String[] words) {
Map<String, Integer> cnt = new HashMap<>();
for (var w : words) {
cnt.put(w, cnt.getOrDefault(w, 0) + 1);
}
int ans = 0, x = 0;
for (var e : cnt.entrySet()) {
var k = e.getKey();
var rk = new StringBuilder(k).reverse().toString();
int v = e.getValue();
if (k.charAt(0) == k.charAt(1)) {
x += v & 1;
ans += v / 2 * 2 * 2;
} else {
ans += Math.min(v, cnt.getOrDefault(rk, 0)) * 2;
}
}
ans += x > 0 ? 2 : 0;
return ans;
}
}
class Solution {
public:
int longestPalindrome(vector<string>& words) {
unordered_map<string, int> cnt;
for (auto& w : words) cnt[w]++;
int ans = 0, x = 0;
for (auto& [k, v] : cnt) {
string rk = k;
reverse(rk.begin(), rk.end());
if (k[0] == k[1]) {
x += v & 1;
ans += v / 2 * 2 * 2;
} else if (cnt.count(rk)) {
ans += min(v, cnt[rk]) * 2;
}
}
ans += x ? 2 : 0;
return ans;
}
};
func longestPalindrome(words []string) int {
cnt := map[string]int{}
for _, w := range words {
cnt[w]++
}
ans, x := 0, 0
for k, v := range cnt {
if k[0] == k[1] {
x += v & 1
ans += v / 2 * 2 * 2
} else {
rk := string([]byte{k[1], k[0]})
if y, ok := cnt[rk]; ok {
ans += min(v, y) * 2
}
}
}
if x > 0 {
ans += 2
}
return ans
}