每日一题——最长回文子串【3.19】

每日一题——最长回文子串【3.19】

题目

  leetcode题目:(链接https://leetcode-cn.com/problems/longest-palindrome)。
  给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。
在构造过程中,请注意区分大小写。比如 “Aa” 不能当做一个回文字符串。
注意:
假设字符串的长度不会超过 1010。

示例 1:

输入:
"abccccdd"

输出:
7

解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。

基本思路

  这个题和两天之前的“单词拼写”那道题有相似之处,归根到底都是统计字符的数量问题。
  我们考虑回文串的特点,在中心点两侧对称位置会有相同的字符,对称中心可以有一个字符也可以没有字符。
  所以,如果某字符是偶数个,那么该字符全部数量都将用来构造回文串。如果某字符是奇数个,那么向下取到的偶数个字符都将用来构造回文串,例如有3个 ‘a’ 时,我们可以向下取到2个来构造回文串。
  最后,至于对称中心有没有字符,我们就可以通过看有没有某个字符是奇数个即可。
  奇数时我们可以用value / 2 * 2来向下取奇数个,当然了,偶数也符合这个公式,所以我们没必要将奇数和偶数分开记数。使用boolean变量来判断是否存在奇数很直接,但更好的我们可以直接使用int型,默认为0,有奇数存在时记为1,最后直接把他加在返回值上更快捷。
优化过程:

  1. 一开始考虑到哈希表可以很方便地存储键值对,所以使用它来记录,最终代码可以通过,但是耗时很长。
  2. 由于这个字符种类是确定的,我们可以用数组来代替哈希表,需要注意的是,ASCII码中大小写字母是不连续的,中间有6个其他字符,所以我们需要长度为26 + 26 + 6 = 58的数组,中间6个空间用不到而已。
  3. 使用数组快了很多,但是没有达到极限速度,不过剩下的都不是很重要的事情了,例如去掉不必要的变量,去掉不必要的数组取值之类的。

具体代码

//Java
class Solution {
	public int longestPalindrome(String s) {
		int longs = 0;
		int hasSingle = 0;
        int[] hashArray = new int[58];
        for(char c : s.toCharArray()) {
        	hashArray[c - 65]++;
        }
        for(int value : hashArray) {
        	if(value % 2 == 1) {
        		hasSingle = 1;
        	}
        	longs = longs + value / 2 * 2;
        }
        return longs + hasSingle;
    }
}

时间复杂度:遍历了一遍s中的所有字母,所以时间复杂度为 O ( n ) O(n) O(n),n表示s的长度。
空间复杂度:空间复杂度为 O ( m ) O(m) O(m),m表示我们开辟的额外空间,使用数组时我们需要58个,如果使用哈希表,我们就需要52个空间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值