【Leetcode】409. Longest Palindrome

题目地址:

https://leetcode.com/problems/longest-palindrome/

给定一个字符串,可以从其中挑选任意多字符,问能组成的最长回文字符串的长度。

可以先统计字符串中各个字符出现的次数,出现偶数次的全部用上,放在两边,出现奇数次的,取出最多偶数个(如果出现 n n n次并且 n n n是奇数,那就取 n / 2 ∗ 2 n/2*2 n/22个,这里除法是计算机里的整除)。最后看一下是否存在字符出现过奇数次,如果存在,就再挑一个字符摆在中间。代码如下:

import java.util.HashMap;
import java.util.Map;

public class Solution {
    public int longestPalindrome(String s) {
        if (s == null || s.isEmpty()) {
            return 0;
        }
        
        Map<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1);
        }
        
        int res = 0;
        boolean odd = false;
        // 将出现偶数次的字符出现的次数直接累加到res上去,并且看一下是否存在出现奇数次的字符
        for (int num : map.values()) {
            res += num / 2 * 2;
            if (num % 2 != 0) {
                odd = true;
            }
        }
        // 如果存在出现奇数次的字符,则再加1,否则不加
        return res + (odd ? 1 : 0);
    }
}

时空复杂度 O ( n ) O(n) O(n)

算法正确性证明:
算法类似贪心法,正确性可以用反证法证明。首先算法里对出现偶数次的字符的对待办法是全拿,如果最优解没有全拿,那可以通过全拿并加在两端的方法构造出一个更长的解,矛盾;其次,对待出现奇数次的字符的方法是拿最大的偶数次,同理这样做也是对的。最后如果有出现奇数次的字符,则随便拿出一个字符摆在正中间即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值