力扣5月17日刷题总结

文章介绍了三个编程问题,包括如何通过移动操作得到字典序最小的字符串,秘密在人群中的传播模型以及数据流中连续整数的检测。对于字符串问题,关键在于理解字符顺序的重要性;秘密传播问题通过动态规划计算在特定条件下知道秘密的人数;数据流问题则需要维护最后k个整数的连续性。
摘要由CSDN通过智能技术生成

(1)有序队列
给定一个字符串 s 和一个整数 k 。你可以从 s 的前 k 个字母中选择一个,并把它加到字符串的末尾。

返回 在应用上述步骤的任意数量的移动后,字典上最小的字符串 。

输入:s = "cba", k = 1 输出:"acb" 解释: 在第一步中,我们将第一个字符(“c”)移动到最后,获得字符串 “bac”。 在第二步中,我们将第一个字符(“b”)移动到最后,获得最终结果 “acb”。
示例 2: 输入:s = "baaca", k = 3 输出:"aaabc" 解释: 在第一步中,我们将第一个字符(“b”)移动到最后,获得字符串 “aacab”。 在第二步中,我们将第三个字符(“c”)移动到最后,获得最终结果 “aaabc”。
*如仔细对该步骤进行分析,即可返现如果k=1,则各个字符间的相等顺序是不变,这是移动首字母n(n=s.size())次。
如果k>1时,仔细想想便知,其顺序是可以随便更改的,直接sort()变出最小字符串。 ==该变换的关键就是各个部分的字符关系顺序不变== 我们也可以将其想象为一个环(但有先后顺序用于比较字符串的大小),k=1时,无论如何变换,都是同一个环,而k>1时,将第x个字符移到最后,进行任意次,其实就相当于将从0到x-1个字符插到环的任意位置。

上代码

class Solution {
public:
    string orderlyQueue(string s, int k) {
        int n=s.size();
        if(k==1)
        {
            string smallest=s;
            for(int i=0;i<n;i++)
            {
                char c=s[0];
                s=s.substr(1);
                s+=c;
                smallest=min(smallest,s);
            }
            return smallest;
        }
        else
        {
            sort(s.begin(),s.end());
            return s;
        }
    }
};

(2)知道秘密的人数
在第 1 天,有一个人发现了一个秘密。
给你一个整数 delay ,表示每个人会在发现秘密后的 delay 天之后,每天 给一个新的人 分享 秘密。同时给你一个整数 forget ,表示每个人在发现秘密 forget 天之后会 忘记 这个秘密。一个人 不能 在忘记秘密那一天及之后的日子里分享秘密。
给你一个整数 n ,请你返回在第 n 天结束时,知道秘密的人数。由于答案可能会很大,请你将结果对 109 + 7 取余 后返回。
思路:
既然每一天都会加一些人,那么就从(当天+delay)开始,往后的gorget日期都加上这些人->表示新增的,直到超过结束日期。
咳咳,现在我们要来算总数了。还记得的人不就是结束日期的前forget天的新增人总数.

我亲爱的一位博主老师提醒我,如果因为该题只涉及加减,所谓的取模可以在使用if(dp[j]>=mod)dp[j]-=mod;
代码:

class Solution {
    #define maxn 1010
    #define mod 1000000007
    int dp[maxn];
public:
    int peopleAwareOfSecret(int n, int delay, int forget) {
        int i,j;
        dp[1]=1;
        for(i=1;i<=n;i++)
        {
            for(j=i+delay;j<i+forget&&j<=n;j++)
            {
                dp[j]+=dp[i];
                if(dp[j]>=mod)dp[j]-=mod;
            }
        }
        int sum=0;
        for(i=n-forget+1;i<=n;i++)
        {
            sum+=dp[i];
            if(sum>=mod)sum-=mod;
        }
        return sum;
    }
};

(3)找到数据流中的连续整数

给你一个整数数据流,请你实现一个数据结构,检查数据流中最后 k 个整数是否 等于 给定值 value 。

请你实现 DataStream 类:

DataStream(int value, int k) 用两个整数 value 和 k 初始化一个空的整数数据流。
boolean consec(int num) 将 num 添加到整数数据流。如果后 k 个整数都等于 value ,返回 true ,否则返回 false 。如果少于 k 个整数,条件不满足,所以也返回 false 。

示例 1:

输入:
[“DataStream”, “consec”, “consec”, “consec”, “consec”]
[[4, 3], [4], [4], [4], [3]]
输出:
[null, false, false, true, false]

解释:
DataStream dataStream = new DataStream(4, 3); // value = 4, k = 3
dataStream.consec(4); // 数据流中只有 1 个整数,所以返回 False 。
dataStream.consec(4); // 数据流中只有 2 个整数
// 由于 2 小于 k ,返回 False 。
dataStream.consec(4); // 数据流最后 3 个整数都等于 value, 所以返回 True 。
dataStream.consec(3); // 最后 k 个整数分别是 [4,4,3] 。
// 由于 3 不等于 value ,返回 False 。

提示:

1 <= value, num <= 109
1 <= k <= 105
至多调用 consec 次数为 105 次。

*该题较简单,在conse中用计数器记录num==value时刻,一但有不满足是,计数器置0.

class DataStream {
public:
    int value,k;
    int cnt=0;
    DataStream(int value, int k) {
        this->value=value;
        this->k=k;
    }
    
    bool consec(int num) {
        if(num==value)cnt++;
        else cnt=0;
        return cnt>=k;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值