题目的主要信息:
删除字符串中出现次数最少的字符,若多个字符出现次数一样,则都删除。输出删除后的字符串,字符串中其它字符保持原来的顺序。
方法一:
首先遍历一遍字符串str,用一个大小为26的数组来统计字符串中各字符出现的次数;然后再遍历一遍这个数组,找到其中的最小值min即为最小的出现次数;最后再遍历一遍字符串,若当前字符的出现次数等于min则不输出,否则输出。
具体做法:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
string str;
while(cin>>str)
{
int min=20;
vector<int> count(26,0);//count用于统计每个字符出现的次数
for(int i=0;i<str.size();i++){//遍历统计每个字符出现的次数
count[str[i]-'a']++;
}
for(int i=0;i<26;i++){//遍历寻找最小的出现次数
if(count[i]<min&&count[i]>0)//不为零表示这个字符在字符串中
min=count[i];
}
for(int i=0;i<str.size();i++){//遍历一遍输出
if(count[str[i]-'a']!=min)//若次数最少则不输出
cout<<str[i];
}
cout<<endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:,需要遍历统计每个字符出现的次数。
- 空间复杂度:,虽然用了count来储存次数,但是count的大小是固定的常数。
方法二:
用min表示目前已经出现的最小次数,min_set为所有出现次数最少的字符合集。首先枚举所有小写字母a-z,用函数countOf计算该字母在字符串中出现的次数count;
- count=0:该字母没有在字符串中出现,不需要考虑。
- count<min:找到了出现次数更小的字母,更新min的值和出现次数相同的字母集合。
- ount==min:把该字母加到集合min_set中。
最后遍历一遍字符串,如果该字符在min_set中没有出现,则输出该字母。 具体做法:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int countOf(char c,string str){//统计字符c在str中出现的次数
int count=0;
for(int i=0;i<str.size();i++){
if(str[i]==c){
count++;
}
}
return count;
}
int main()
{
string str;
while(cin>>str)
{
int min=20;
string min_set;
for(char i='a';i<='z';i++){//枚举所有小写字母
int count=countOf(i,str);
if(count==0) continue;//count=0表示该字母没有在字符串中出现,不需要考虑
if(count<min){//找到了出现次数更小的字母,更新min的值和出现次数相同的字母集合
min_set=i;
min=count;
}else if(count==min){//如果出现次数和min相同,则加到集合min_set中
min_set+=i;
}
}
for(int i=0;i<str.size();i++){
if(min_set.find(str[i])==min_set.npos){//如果在min_set中没有找到当前字母则输出
cout<<str[i];
}
}
cout<<endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:,需要遍历一遍输出字符;枚举所有小写字母的for循环时间复杂度为。
- 空间复杂度:,最坏情况下min_set==str,大小为。