(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时,仔细想想便知,其顺序是可以随便更改的,直接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;
}
};