题目:3304. 找出第 K 个字符 I
思路:模拟,时间复杂度0(k)
class Solution {
public:
char kthCharacter(int k) {
string s="a";
while(s.size()<k){
int n=s.size();
for(int i=0;i<n;i++){
if(s[i]=='z') s.push_back('a');
else s.push_back(s[i]+1);
}
}
return s[k-1];
}
};
题目:3305. 元音辅音字符串计数 I
思路:直接枚举字符串的左右端点,时间复杂度为0(n^3)
class Solution {
public:
int pd(char x,int u,int a[],int &ans){
if(x=='a'){
a[0]+=u;
if(a[0]==0) ans++;
if(a[0]==1) ans--;return 0;
}else if(x=='e'){
a[1]+=u;
if(a[1]==0) ans++;
if(a[1]==1) ans--;return 0;
}else if(x=='i'){
a[2]+=u;
if(a[2]==0) ans++;
if(a[2]==1) ans--;return 0;
}else if(x=='o'){
a[3]+=u;
if(a[3]==0) ans++;
if(a[3]==1) ans--;return 0;
}else if(x=='u'){
a[4]+=u;
if(a[4]==0) ans++;
if(a[4]==1) ans--;return 0;
}else return 1;
}
int countOfSubstrings(string word, int k) {
long long res=0;
//元音字母的情况
int a[5];
for(int i=0;i<word.size();i++){
for(int j=i;j<word.size();j++){
memset(a,0,sizeof a);
//辅音字母的数量
int fy=0;
int ans=5;
for(int k=i;k<=j;k++){
fy+=pd(word[k],1,a,ans);
}
if(ans==0&&fy==k) res++;
}
}
return res;
}
};
题目:3306. 元音辅音字符串计数 II
思路:“辅音字母出现个数为k”可以转变为:“辅音字母出现个数至少为k” 减去“辅音字母出现个数至少为k+1”
class Solution {
public:
long long solve(string word, int k){
long long ans=0;
//元音字母
string s="aeiou";
//记录滑动窗口中元音字母的情况
unordered_map<char,int> mp;
//辅音字母
int fy=0;
//滑动窗口的左端点
int left=0;
//滑动窗口的右端点
for(auto x:word){
//为元音字母
if(s.find(x)!=string::npos){
mp[x]++;
}else{
//辅音字母
fy++;
}
//如果元音字母均出现,且辅音字母至少为k,那就可以移动左端点left,看其可以移动到的最远地方。直到不符合其中一个条件,那么在当前右端点的情况下,左端点的个数就为left个
while(mp.size()==5&&fy>=k){
char y=word[left++];
//元音字母
if(s.find(y)!=string::npos){
//减去
mp[y]--;
//为0的话,就删除该键值对
if(mp[y]==0) mp.erase(y);
}else{
//辅音字母
fy--;
}
}
ans+=left;
}
return ans;
}
long long countOfSubstrings(string word, int k) {
//“辅音字母出现个数至少为k” 减去“辅音字母出现个数至少为k+1”
return solve(word,k)-solve(word,k+1);
}
};
题目:3307. 找出第 K 个字符 II
思路:从后往前推算第k个字符是由前面哪个字符推算出来的,并同时记录操作情况。细节看注释,时间复杂度0(n)。
class Solution {
public:
char kthCharacter(long long k, vector<int>& operations) {
//找到>=k的最近的倍数
long long K=1;
//翻倍次数
int ans=0;
while(K<k){
K<<=1;
ans++;
}
//记录从后往前时,需要进行的操作
stack<int> st;
for(int i=ans-1;i>=0;i--){
//翻倍之前,字符串的长度
K>>=1;
//如果k大于K,那么说明在翻倍的里面
if(K<k){
//更新它在字符串中的位置
k-=K;
//并记录翻倍的操作,因为该操作会影响到它
st.push(operations[i]);
}
//cout<<endl<<k<<'-'<<K;
}
//执行操作
char s='a';
while(st.size()){
if(st.top()==1){
if(s=='z') s='a';
else s+=1;
}
st.pop();
}
return s;
}
};