携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第26天,点击查看活动详情
前言
小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标300题,记录从0到1的全过程!!
2131. 连接两字母单词得到的最长回文串
这是69场双周赛的第三题
2131. 连接两字母单词得到的最长回文串
给你一个字符串数组 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] 仅包含小写英文字母
2.解法一 HashMap
class Solution {
public int longestPalindrome(String[] words) {
HashMap<String, Integer> map = new HashMap<>();
int t = 0;
int same = 0;
for(int i = 0; i < words.length; i++) {
String reverse = ""+words[i].charAt(1) + words[i].charAt(0);
if(map.containsKey(reverse)) {
t= t+2;
if(map.get(reverse) == 1) {
map.remove(reverse);
} else {
map.put(reverse,map.get(reverse)-1);
}
} else {
if(map.containsKey(words[i])) {
map.put(words[i],map.get(words[i])+1);
} else {
map.put(words[i],1);
}
}
}
for(String s : map.keySet()) {
if(s.charAt(0)==s.charAt(1)) {
same++;
break;
}
}
return (t + same) * 2;
}
}
提交排名
解析
这个题最低也是O(n)的时间复杂度,那就首先for循环遍历整个数组,关键是怎么判断遍历的这个对应的字符,能不能添加到最后的结果中呢?
这里我引入了一个hashmap,他的key就是字符对,value是这个字符还有几次没用。
第一步,对于任意一个字符"ab",我们去hashmap中找有没有"ba",如果找到了,结果t++,并把"ba"对应的值--;如果没有找到就把"ab"放入map中,遍历完之后,map中存放的就是没有对应的字符串了。
第二步,遍历map,找到是否存在"aa"类型的字符串,如果找到就讲same++;并且直接返回。
第三步,返回结果t+same的两倍就可以了。
2.解法二 数组
class Solution {
public int longestPalindrome(String[] words) {
char[][] chars = new char[26][26];
int t = 0;
int same = 0;
for(int i = 0; i < words.length; i++) {
int c1 = words[i].charAt(0) - 'a';
int c2 = words[i].charAt(1) - 'a';
if(chars[c2][c1]>0) {
t = t + 2;
chars[c2][c1]--;
} else {
chars[c1][c2]++;
}
}
for (int i = 0; i < 26; i++) {
if(chars[i][i]>0) {
same++;
break;
}
}
return (t + same) * 2;
}
}
提交排名
解析
map的添加删除查询等操作确实太多了,会导致运行时间过长,因为字母数量是26个优先的,那所有字符串也都可以包含在char[26][26]的数组中,这样用这样的二维数组代替map,就可以使得运行效率更高了。
3.结束
这个题作为当时周赛的第三题,并不算难,周赛的时候能用map来ac也是可以的,map的思路容易想到,但是实现起来还是比数组要复杂一些。gogogo,刷题刷题,每天一道,三年1000道!!!!