题目的主要信息:

  • 输入的字符串由26个字母组成,大小写都有
  • 定义这个字符串的“漂亮度”是其所有字母“漂亮度”的总和
  • 每个字母都有一个“漂亮度”,范围在1到26之间,没有任何两个不同字母拥有相同的“漂亮度”
  • 漂亮度统计时字母忽略大小写

方法一:排序

具体做法:

题目的意思就是26个字母每个字母有一个1-26的漂亮度,不重复,要是该字符串漂亮度最大,则直接使它里面出现次数最多的字符漂亮度最大即26,出现次多的字符漂亮度为25,以此递减,然后相加就会得到最大的漂亮度。

我们可以用一个长度为26的数组统计每个字符串出现的次数,然后对数组进行排序,从数组末尾开始遍历数组,末尾的即最多的次数乘上最高漂亮度26,往前遍历漂亮度依次递减相加即可。

alt

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

int main(){
    int n;
    while(cin >> n){
        while(n--){
            string s;
            cin >> s;
            vector<int> count(26, 0); //用于统计26个字母每个字符串中出现的次数
            for(int i = 0; i < s.length(); i++){  //遍历字符串统计字母出现次数
                if(s[i] >= 'a' && s[i] <= 'z') //小写字母
                    count[s[i] - 'a']++;
                else   //大写字母
                    count[s[i] - 'A']++; 
            }
            sort(count.begin(), count.end()); //出现次数排序
            int output = 0;
            int k = 26;
            for(int i = 25; i >= 0; i--){ //出现次数最多的漂亮度最大26,依次递减
                output += count[i] * k;
                k--;
            }
            cout << output << endl;
        }
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(n)O(n),其中nn为字符串的长度,排序的数组和累加计算漂亮度都是26,常数时间
  • 空间复杂度:O(1)O(1),辅助数组的长度为26,常数空间

方法二:哈希表+优先队列

具体做法:

我们也可以用一个无序哈希表统计每个字符串出现的次数,然后遍历哈希表将value值加入一个优先队列中进行排序,最后依次弹出优先队列中的元素,也是从漂亮度最大26开始乘,后面漂亮度递减,不断累加。

这个方法如果字符集不足26个字母的时候时间空间都会更低一些。

#include<iostream>
#include<string>
#include<queue>
#include<unordered_map>
#include<algorithm>
using namespace std;

int main(){
    int n;
    while(cin >> n){
        while(n--){
            string s;
            cin >> s;
            unordered_map<char, int> mp;
            for(int i = 0; i < s.length(); i++){
                char c = tolower(s[i]); //将字母全部转为小写
                mp[c]++; //哈希表统计每个字母出现次数
            }
            priority_queue<int> pq;
            for(auto iter = mp.begin(); iter != mp.end(); iter++) //遍历哈希表
                pq.push(iter->second); //将value值加入优先队列
            int output = 0;
            int k = 26; 
            while(!pq.empty()){ //遍历优先队列
                output += pq.top() * k; //次数最多的用26开始设置漂亮度
                pq.pop();
                k--;
            }
            cout << output << endl;
        }
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(n)O(n),其中nn为字符串的长度,遍历字符串统计为O(n)O(n),遍历哈希表加入复杂度为字符集,常数时间,后面优先队列排队和弹出也是常数时间
  • 空间复杂度:O(1)O(1),辅助数组的长度为26,常数空间