强化训练:day13(牛牛冲钻五、最长无重复子数组、重排字符串)

前言

  1. 牛牛冲钻五
  2. 最长无重复子数组
  3. 重排字符串

1. 牛牛冲钻五

1.1 题目描述

在这里插入图片描述

1.2 解题思路

  使用前缀和思路统计出结束当前对局连胜数量,再根据连胜数量依次加上星星就可以了。

1.3 代码实现

#include <iostream>
using namespace std;
#include <string>
#include <vector>
int main()
{
    int t = 0; cin >> t;
    while(t--)
    {
        int n = 0, k = 0; cin >> n >> k;
        string s; cin >> s;
        vector<int> dp(n, 0);
        dp[0] = s[0] == 'W' ? 1 : 0;
        // 统计连胜
        for(int i = 1; i < n; i++)
        {
            if(s[i] == 'W') dp[i] = dp[i-1] + 1;
        }
        int ret = 0;
        for(int i = 0; i < n; i++)
        {
            if(s[i] == 'W')
            {
                if(dp[i] >= 3) ret += k;
                else ret += 1;
            }
            else
            {
                ret -= 1;
            }
        }
        cout << ret << endl;
    }
}

2. 最长无重复子数组

2.1 题目描述

在这里插入图片描述

2.2 解题思路

  典型的滑动窗口的问题,使用双指针来维护我们需要的合法区间即可。

2.3 代码实现

class Solution {
  public:
    // 滑动窗口
    int maxLength(vector<int>& nums) 
    {
        int ret = 0;
        int n = nums.size();
        // 维护一段有效区间
        int left = 0, right = 0;
        // 判断前面是否出现过这个数字
        unordered_set<int> hash;
        while (right < n)
         {
            while (right < n && hash.count(nums[right]) == 0) 
            {
                hash.insert(nums[right++]);
            }
            ret = max(ret, right - left);
            while (hash.count(nums[right]) == 1) 
            {
                hash.erase(nums[left++]);
            }
        }
        return ret;
    }
};

3. 重排字符串

3.1 题目描述

在这里插入图片描述

3.2 解题思路

  想要将不同的字符串进行分割,只要出现次数最多的字符没有超过总字符的一半,那么就可以重排成功。因为我们采用的方法是,隔上一个方一个字符,就比如第一个位置放字符a,下一个就到第三个位置放字符a,通过这样的放置方法,来实现所有相同字符的分隔。所以当出现次数最多的字符超过总字符的一半时,那么就无论如何都无法将相同字符进行分隔了,直接返回就行了。
  因为我们可以先使用哈希表,统计出每一个字符出现的次数,以及最多出现的次数和最多出现的字符,先放置出现次数最多的字符,防止这种情况:aaabbbb ----> abababb。因此需要先放置出现最多的字符。

3.3 代码实现

#include <iostream>
using namespace std;
#include <string>
#include <vector>
#include <cstring>
int main()
{
    int n = 0; cin >> n;
    string s; cin >> s;
    int hash[26];
    memset(hash, 0 ,sizeof hash);
    int maxCount = 0,maxIndex = 0;
    for(int i = 0; i < n; i++)
    {
        int ch = s[i] - 'a';
        hash[ch]++;
        if(hash[ch] > maxCount)
        {
            maxCount = hash[ch];
            maxIndex = ch;
        }
    }
    if((n + 1) / 2 < maxCount)
    {
        cout << "no";
        return 0;
    }
    vector<string> ret(n);
    int cur = 0;
    while(maxCount--)
    {
        ret[cur] = maxIndex + 'a';
        cur += 2;
    }
    
    for(int i = 0; i < 26; i++)
    {
        if(hash[i] && i != maxIndex)
        {
            while(hash[i]--)
            {
                if(cur >= n) cur = 1;
                ret[cur] = i + 'a';
                cur += 2;
            }
        }
    }
    cout << "yes" << endl;
    for(int i = 0; i < n; i++)
    {
        cout << ret[i];
    }
    return 0;
}

总结

  前两个题都是由固定的算法思路,进行专项训练就可以了,至于第三个题那么就只能看个人的想法了。不过多做题肯定是没错的,希望大家可以继续练习下去。
  那么第十三天的内容就到此结束了,如果大家发现有什么错误的地方,可以私信或者评论区指出喔。我会继续坚持训练的,希望能与大家共同进步!!!那么本期就到此结束,让我们下期再见!!觉得不错可以点个赞以示鼓励!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不如小布.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值