(nice!!!)LeetCode 3035. 回文字符串的最大数量(贪心、哈希表)

题目:3035. 回文字符串的最大数量

在这里插入图片描述
在这里插入图片描述

方法一:先统计出所有字符出现的次数。然后将字符串的长度按升序排序。接着就可以模拟构造回文字符串。细节看注释

class Solution {
public:
    int maxPalindromesAfterOperations(vector<string>& words) {
        int a[30];
        memset(a,0,sizeof a);
        vector<int> v;
        //统计出所有字符出现的次数
        for(int i=0;i<words.size();i++){
            for(auto x:words[i]){
                a[x-'a']++;
            }
            v.push_back(words[i].size());
        }
        //统计出,单个字符和双个字符的次数
        int ct1=0,ct2=0;
        for(int i=0;i<26;i++){
            if(a[i]){
                if(a[i]%2){
                    ct1++;
                    ct2+=a[i]-1;
                }else{
                    ct2+=a[i];
                }
            }
        }
        //将字符串的长度按升序排序
        sort(v.begin(),v.end());
        int ans=0;
        for(int i=0;i<v.size();i++){
        	//如果是奇数长度
            if(v[i]%2){
            	//单个字符还有多余
                if(ct1){
                	//且双个字符也足够
                    if(ct2>=v[i]-1){
                        ans++;
                        ct1--;
                        ct2=ct2-(v[i]-1);
                    }
                }else{
                	//单个字符没有多余,且双个字符拆开一对,还是足够
                    if(ct2-2>=v[i]-1){
                        ans++;
                        ct1++;
                        ct2=ct2-2-(v[i]-1);
                    }
                }
            }else{
            //如果是偶数长度
            	//且双个字符也足够
                if(ct2>=v[i]){
                    ans++;
                    ct2-=v[i];
                }
            }
        }
        return ans;
    }
};

方法二:统计出所有字符的数量总和sum,然后减去数量为奇数的字符种类。最后进行回文字符串的构造,细节看注释。

class Solution {
public:
    int maxPalindromesAfterOperations(vector<string>& words) {
    	//记录出字符出现的奇偶数状态
        int sta=0;
        //统计出所有字符的数量总和
        int sum=0;
        vector<int> v;
        for(int i=0;i<words.size();i++){
            for(auto x:words[i]){
                sum++;
                sta=sta^(1<<(x-'a'));
            }
            v.push_back(words[i].size());
        }
        //减去数量为奇数的字符种类
        for(int i=25;i>=0;i--){
            if(sta>>i&1) sum--;
        }
        int ans=0;
        //将字符串的长度按升序排序
        sort(v.begin(),v.end());
        //对于奇数长度的字符串,只需要考虑除中间字符的两侧。而字符总数的数量是确定的,减去数量为奇数的字符种类,剩下的都是成对字符的总数量。接着只需要考虑这些成对的字符是否可以组成回文字符串即可。
        //原理就是:单个字符可以由偶数个字符拆分得到,但是偶数字符是无法增加的。
        for(auto x:v){
        	//这里只需要考虑字符串长度的偶数部分
            sum-=x/2*2;
            if(sum<0) break;
            ans++;
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值