描述
实现删除字符串中出现次数最少的字符,若出现次数最少的字符有多个,则把出现次数最少的字符都删除。输出删除这些单词后的字符串,字符串中其它字符保持原来的顺序。
数据范围:输入的字符串长度满足 1 \le n \le 20 \1≤n≤20 ,保证输入的字符串中仅出现小写字母
输入描述:
字符串只包含小写英文字母, 不考虑非法输入,输入的字符串长度小于等于20个字节。
输出描述:
删除字符串中出现次数最少的字符后的字符串。
题目来源
示例1
输入:
aabcddd
复制
输出:
aaddd
思路
-
法1:手动实现hash表
- 1.统计各个字符出现的次数,用char c[127],O(n)
- 2.找到统计次数中最小的次数,赋值为min,O(n)
- 3.遍历字符串,将字符出现的次数对比min,大于min则加入到ans字符串中,小于则不管
-
法2:hash表法
- 1.设置hash表,map<char,int>
- 2.统计各个字符出现的次数
- 3.找到统计次数中最小的次数,赋值为min
- 同思路1.3
时间复杂度
法1:时间复杂度:O(3n),空间复杂度:O(n)
法2:时间复杂度:O(n),空间复杂度O(n)
具体实现
#include <math.h>
#include <algorithm>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <stdlib.h>
#include <cstdlib>
#include <cstring>
using namespace std;
const int INF = 1e8;
//day4,
//实现删除字符串中出现次数最少的字符,若出现次数最少的字符有多个,则把出现次数最少的字符都删除。输出删除这些单词后的字符串,字符串中其它字符保持原来的顺序。
//法1:非原地算法
//时间复杂度:O(n),空间复杂度O(n)
/**
* @description:
* @param {string &} s
* @return {*}
*/
string DeletAllMinCharacter(string s){
char c[127] = {0};//记录对应字符出现的次数
char c_m[127] = {0};//记录最小字符数的对应字符
string ans;//答案字符串
int len_s = s.length();
int min = INF;//记录最少的字符数
for(int i = 0; i < len_s; i++){
c[s[i]]++;//记录对应的字符数
}
//统计最小的字符数据
for(int i = 0; i < 127; i++){
if(c[i] < min && c[i] != 0) min = c[i];
}
//将答案字符串直接赋给ans
for(int i = 0; i < len_s; i++){
if(c[s[i]] > min) ans += s[i];
}
return ans;
}
//法2:利用库函数的hash表进行统计遍历
/**
* @description: 时间复杂度:O(n) 空间复杂度O(n)
* @param {string} s
* @return {*}
*/
string DeletAllMinCharacterII(string s){
unordered_map<char,int>hash;//记录出现次数的hash表
int degree = INF;
string ans;
for(int i = 0; i < s.length(); i++){
hash[s[i]]++;
}
//统计出出现最少的次数
for(auto & k : hash){
degree = min(degree, k.second);
}
//printf("%d",degree);
//根据最少次数进行遍历,将大于最少次数的字符统一加到s[i]中
for(int i = 0; i < s.length(); i++){
if(hash[s[i]] > degree) ans += s[i];
}
return ans;
}
int main(){
string s;
string ans;
//用到getline
getline(cin,s);//将输入流直接赋给s字符串
//char c;
//cin >> c;
//int lastans = CountDifferentCharacter(s);
ans = DeletAllMinCharacter(s);
for(int i = 0; i < ans.lenght(); i++){
printf("%c",ans[i]);
}
//printf("%d",lastans);
system("pause");
return 0;
}
小结
此类统计字符的次数,第一次思考对象为hash表法,法1和法2均为非原地算法,但是因为输入字符<=20,那么空间复杂度为O(1),并不影响空间复杂度;
但如果是出现输入字符不限制,原地算法较为好,无额外空间消耗,但是原地算法我并没有想出来,后序查询百度是否可以实现原地删除