LeetCode算法题-Longest Palindrome(五种解法)
这是悦乐书的第220次更新,第232篇原创
01 看题和准备
今天介绍的是LeetCode算法题中Easy级别的第87题(顺位题号是409)。给定一个由小写或大写字母组成的字符串,找到可以用这些字母构建的最长的回文长度。这是区分大小写的,例如“Aa”在这里不被视为回文。例如:
输入:“abccccdd”
输出:7
说明:可以建造的最长的回文是“dccaccd”,其长度为7。
注意:假设给定字符串的长度不超过1,010。
本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。
02 第一种解法
给定的字符范围是大小写字母,因此使用一个长度为256的整型数组,来存储字符串s中每个字符出现的次数。想要构成回文,字符串中的各个字符出现的次数分为两种情况:一是该字符出现偶数次,二是该字符出现奇数次。出现偶数次可以直接拿来使用,只要放在对称位置即可;出现奇数次时,如果是1次,那么该字符只能当做回文的中心且只能用一次,如果大于1次,则其偶数次部分可以直接使用,并且多余的1次可以当做回文的中心且只能使用一次。
此解法的时间复杂度是O(n),空间复杂度是O(1)。
public int longestPalindrome(String s) {
int[] arr = new int[256];
for (int i=0; i<s.length(); i++) {
arr[s.charAt(i)]++;
}
int count = 0;
int single = 0;
for (int j=0; j<arr.length; j++) {
if (arr[j]%2 == 0) {
count += arr[j];
} else {
count += arr[j]-1;
single = 1;
}
}
return count+single;
}
03 第二种解法
此解法的思路和第一种解法一致,只是在计数判断那里有点区别。对数组中当前元素直接除以2得到商,再乘以2,得到当前字符可以使用的次数,但是同样需要判断奇数次元素,如果当前元素是奇数,并且count是偶数,即count之前没遇到奇数,那么count自加1,并且只会执行一次,因为回文字符串中心只能是一次。
此解法的时间复杂度是O(n),空间复杂度是O(1)。
public int longestPalindrome2(String s) {
int[] arr = new int[256];
for (int i=0; i<s.length(); i++) {
arr[s.charAt(i)]++;
}
int count = 0;
for (int j=0; j<arr.length; j++) {
count += (arr[j]/2)*2;
if (arr[j]%2 == 1 && count%2 == 0) {
count++;
}
}
return count;
}
04 第三种解法
此解法思路和第二种解法一致,有区别的是判断出现奇数次字符并且count加1的逻辑从循环体中抽出来了,放在了最后。如果count和字符串s的长度做比较时,相等则说明s中的字符都是出现偶数次,不相等则说明s中有出现奇数次的字符,count就需要加1,且只能加1次。
此解法的时间复杂度是O(n),空间复杂度是O(1)。
public int longestPalindrome3(String s) {
int[] arr = new int[256];
for (int i=0; i<s.length(); i++) {
arr[s.charAt(i)]++;
}
int count = 0;
for (int j=0; j<arr.length; j++) {
count += (arr[j]/2)*2;
}
return count == s.length() ? count : count+1;
}
05 第四种解法
使用HashSet,如果当前字符已经在set中存在,那么count加2,并且要移除当前字符;如果不存在,就add进set中。最后判断set是否为空,如果不为空,则说明有些字符出现了奇数次,就只能当做回文字符组中心来用,且只能用一次。
此解法的时间复杂度是O(n),虽然使用了contains方法,但是HashSet内存储的数据不会达到O(n)规模,因此遍历判断是否包含当前字符需要的最多判断次数为52次,即O(52*n),也即O(n)。
空间复杂度是O(1),虽然使用了HashSet,但是字符的范围只是大小写字母,最大长度是52,可以看做是一个常量。
public int longestPalindrome4(String s) {
Set<Character> set = new HashSet<Character>();
int count = 0;
for (int i=0; i<s.length(); i++) {
if (set.contains(s.charAt(i))) {
count = count + 2;
set.remove(s.charAt(i));
} else {
set.add(s.charAt(i));
}
}
if (!set.isEmpty()) {
count = count + 1;
}
return count;
}
06 第五种解法
参照第四种解法的思路,我们同样可以使用数组来操作。数组的长度控制在58,因为a到z是从97到122,A到Z是从65到90,中间相隔58个数。将s变为字符数组,如果当前字符表示的十进制数,在数组中对应的元素为0就自加1,否则就自减1,然后count加2,最后再去判断数组中的元素有没有大于0的存在,如果存在即表示有字符出现了奇数次,然后count需要加1,且只用加一次。
public int longestPalindrome5(String s) {
int[] arr = new int[58];
int count = 0;
for (char ch : s.toCharArray()) {
if (arr[ch-'A'] == 0) {
arr[ch-'A']++;
} else {
arr[ch-'A']--;
count += 2;
}
}
for (int j=0; j<arr.length; j++) {
if (arr[j] > 0) {
count += 1;
break;
}
}
return count;
}
07 小结
算法专题目前已连续日更超过两个月,算法题文章87+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。
以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!
LeetCode算法题-Longest Palindrome(五种解法)的更多相关文章
- LeetCode算法题-Longest Word in Dictionary(Java实现)
这是悦乐书的第303次更新,第322篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第171题(顺位题号是720).给出表示英语词典的字符串单词数组,找到单词中长度最长的单 ...
- LeetCode算法题-Longest Univalue Path(Java实现)
这是悦乐书的第290次更新,第308篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第158题(顺位题号是687).给定二叉树,找到路径中每个节点具有相同值的最长路径的长度 ...
- LeetCode算法题-Valid Palindrome II(Java实现)
这是悦乐书的第287次更新,第304篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第155题(顺位题号是680).给定非空字符串s,最多可以删除一个字符. 判断它是否是回 ...
- LeetCode算法题-Longest Continuous Increasing Subsequence(Java实现)
这是悦乐书的第286次更新,第303篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第154题(顺位题号是674).给定未排序的整数数组,找到最长连续增加子序列的长度.例如 ...
- LeetCode算法题-Longest Harmonious Subsequence(Java实现)
这是悦乐书的第270次更新,第284篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第136题(顺位题号是594).我们定义一个和谐数组是一个数组,其最大值和最小值之间的差 ...
- LeetCode算法题-Longest Uncommon Subsequence I(Java实现)
这是悦乐书的第252次更新,第265篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第119题(顺位题号是521).给定一组两个字符串,您需要找到这组两个字符串中最长的不同 ...
- LeetCode算法题-Valid Palindrome(Java实现)
这是悦乐书的第174次更新,第176篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第33题(顺位题号是125).给定一个字符串,确定它是否是回文,只考虑字母数字字符并忽略 ...
- 【算法】LeetCode算法题-Longest Common Prefix
这是悦乐书的第146次更新,第148篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第5题(顺位题号是14),给定一个随机的字符串数组,查找这些字符串元素的公共前缀字符串, ...
- LeetCode算法题-Number Complement(Java实现-五种解法)
这是悦乐书的第240次更新,第253篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第107题(顺位题号是476).给定正整数,输出其补码数.补充策略是翻转其二进制表示的位 ...
随机推荐
- man sm-notify(sm-notify命令中文手册)
本人译作集合:http://www.cnblogs.com/f-ck-need-u/p/7048359.html sm-notify命令是用来发送重启通知信息给NFS对端的,在锁状态恢复过程中起着至关 ...
- Perl:写POD文档
官方手册:https://perldoc.perl.org/perlpod.html POD文档是perl的man文档,可以用perldoc输出,也可以直接用man输出.在开始下面的文章之前,请先粗略 ...
- SpringBoot学习(五)-->SpringBoot的核心
SpringBoot的核心 1.入口类和@SpringBootApplication Spring Boot的项目一般都会有*Application的入口类,入口类中会有main方法,这是一个标准的J ...
- Redis学习笔记(3)-XShell连接CentOSMini,并安装Redis
使用XShell远程连接CentOSMini 点击download下载XShell5.0. 下载之后安装.配置XShell. 配置XShell前的准备 打开VM,启动CentOSMini.CentOS ...
- WebAPI参数传值string转bool,int转bool相关问题
今天在公司同事问了我一个问题,用postman传递json字符串给接口,接口获取到的值不正确. 我就看到下面的json数据: { "Mark":"1" } 接口 ...
- C#中设置窗口在最前显示而其他窗口不能使用
对程序中的一个Form1处理,让其在打开的情况下,其他窗体都无法使用,全部焦点都在他身上. 1.这种方法最简单,直接调用窗体的模态对话框函数显示窗体 Form1.ShowDialog(): 2.设置窗 ...
- 记录ThreadPoolTaskExecutor线程池的在项目中的实际应用,讲解一下线程池的配置和参数理解。
前言:最近项目中与融360项目中接口对接,有反馈接口(也就是我们接收到请求,需要立即响应,并且还要有一个接口推送给他们其他计算结果),推送过程耗时.或者说两个接口不能是同时返回,有先后顺序. 这时我想 ...
- Netty实战十之编解码器框架
编码和解码,或者数据从一种特定协议的格式到另一种格式的转换.这些任务将由通常称为编解码器的组件来处理.Netty提供了多种组件,简化了为了支持广泛的协议而创建自定义的编解码器的过程.例如,如果你正在构 ...
- express入门
(1)express的安装 $ npm install express 或者 $ npm install -g express 或者 $ npm install express -gd 备注: -g ...
- ITEXT5.5.8转html为pdf文档解决linux不显示中文问题
在windows中支持中文,在linux中不显示中文. 解决方法:添加字体库 下载simsun.ttc字体文件,把这文件拷贝到Linux系统的 /usr/share/fonts/ 下就可以了.