感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒 个人主页
🥸🥸🥸 C语言
🐿️🐿️🐿️ C语言例题
🐣🐣🐣 python
🐓🐓🐓 数据结构C语言
🐔🐔🐔 C++
🐿️🐿️🐿️ 文章链接目录
🏀🏀🏀 笔试练习题
牛牛冲钻五
题目解析
这道题要考虑到连胜奖励,如果触发了那么一把就不是只加1颗星,而是加k颗星,输了的话那么就掉一颗星,同时连胜次数归零
代码
#include<iostream>;
#include<string>;
using namespace std;
int main()
{
int T = 0;
cin >> T;
int n, k, count = 0, sum = 0;
while (T--)
{
string s;
cin >> n >> k;
cin >> s;
for (int i = 0; i < n; i++)
{
if (s[i] == 'W')
{
count++;
if (count >= 3)
sum += k;
else
sum++;
}
else
{
count=0;
sum--;
}
}
cout << sum << endl;
sum=0;
count=0;
}
return 0;
}
NC41 最长无重复子数组
题目解析
这道题可以用滑动窗口去求解
什么情况可以用滑动窗口呢,比如这道题,我们如果用双指针的暴力解法的话会发现时间复杂度为n^2,这样会超时,并且用双指针会让后一个指针回退,然后继续遍历,发生这种情况是因为他们有相同的数字导致了回退
比如下面这种情况
如果我们让j回退回去再遍历的话,我们会发现j还是会在1那个位置停下,这完全是没有必要的,所以我们发现i和j在这种情况下是可以同向移动的
滑动窗口的基本步骤是1:进窗口 2:判断 3:出窗口 4:更新结果
1:进窗口,将right所指的元素进窗口,然后将这个元素统计进hash表中
2:判断,判断是否有重复元素,有的话就出窗口
3:出窗口,此时需要将left所指向的元素出窗口,然后left往后走,如果发现left所指的元素还是在hash表中重复了,那么就移除,继续判断
如果发现没有重复的就让right往后走
代码
class Solution {
int hash[100001]={0};
public:
int maxLength(vector<int>& arr) {
int left=0,right=0,n=arr.size();
int ret=0;
while(right<n)
{
hash[arr[right]]++;
while(hash[arr[right]]>1)
{
hash[arr[left]]--;
left++;
}
ret=max(ret,right-left+1);
right++;
}
return ret;
}
};
重排字符串(需要重做)
题目解析
题目中有句话比较绕 不包含任意两个相同的相邻字母,其实是指的相邻两个字符的字母是不一样的,比如bcb就符合,而baa就不符合
这道题的解法是贪心
优先处理相同的字母,比如例子2
我们可以先处理a,此时a如果我们先填入第一个空,那么他除了左右两个空不能填a,其他的都可以填
此外我们除了优先处理相同的字母以为,还需要考虑到如果相同的字母非常多,我们也应该优先处理他
并且我们插入的方法也需要注意,虽然可插入的空非常多,但是我们应该优先选择第一种,因为第一种两个字母之间只需要再插入一个其他的字母就可以了,而其他情况中,我们可以需要在中间插入多个字母,很有可能会因为其他字母的数量不够导致出问题
这样摆之后,其他的字母只需要插在他们之间就看可以了,不需要考虑是否相邻
判断能不能重排我们需要考虑出现次数最多的字母是否满足他的总数小于或等于总字母数的一半
这个例子就是总字母数为10,而C的个数为6,因为6>5,所以不能重排,当C的个数<=5的时候可以
也就是满足下面这一个公式
代码
#include<iostream>;
using namespace std;
const int N=1e5+10;
int cnt[26]={0};
char s[N];
char ret[N];
int n;
int main()
{
cin>>n>>s;
char maxChar=0;
int maxCount=0;
for(int i=0;i<n;i++)
{
int index=s[i]-'a';
if(++cnt[index]>maxCount)
{
maxChar=s[i];
maxCount=cnt[index];
}
}
if(maxCount>(n+1)/2)cout<<"no"<<endl;
else{
cout<<"yes"<<endl;
int i=0;
while(maxCount--)
{
ret[i]=maxChar;
i+=2;
}
for(int j=0;j<26;j++)
{
if(cnt[j]&&j+'a'!=maxChar)
{
while(cnt[j]--)
{
if(i>=n)i=1;
ret[i]=j+'a';
i+=2;
}
}
}
for(int i=0;i<n;i++)cout<<ret[i];
cout<<endl;
}
return 0;
}
代码解析
char s[N]是用来存储字符串
char ret[N]是用来存重排后的字符串
maxChar和maxCount表示出现最多的字符和他出现了多少次
cnt[26]是哈希表统计每个字符出现的次数
int index=s[i]-'a’是记录对应哈希表的下标
if(++cnt[index]>maxCount)是一边统计一边判断,如果进入if语句里面就更改maxChar和maxCount
{
maxChar=s[i];
maxCount=cnt[index];
}
if(maxCount>(n+1)/2)判断是否能重排
如果能就进行重排,循环maxCount次,每个字母中间隔一个空,所以 i+=2
后面处理剩下的字符,通过遍历哈希表找出剩下的字符,但是要主要之前maxChar已经填过了,所以还需要判断 if( cnt[ j ]&& j+ ‘a’ != maxChar)
后面就开始填字母,总共填cnt[j]次,因为之前是从i=0开始填的,可能后面没有填完
当后面填完后我们判断i>=n,那么就让i从1开始继续填