Every day a Leetcode
题目来源:2182. 构造限制重复的字符串
解法1:贪心 + 双指针
我们先用一个长度为 26 的数组 cnt 统计字符串 s 中每个字符出现的次数,然后从大到小枚举字母表的第 i 个字母,每次取出最多 min(cnt[i], repeatLimit) 个字母 i,如果取完后 cnt[i] 还大于 0,则继续取字母表中第 j 个字母,其中 j 是最大的满足 j<i 且 cnt[j]>0 的下标,直到取完所有字母。
代码:
/*
* @lc app=leetcode.cn id=2182 lang=cpp
*
* [2182] 构造限制重复的字符串
*/
// @lc code=start
class Solution
{
public:
string repeatLimitedString(string s, int repeatLimit)
{
// 特判
if (s.empty() || repeatLimit <= 0)
return "";
vector<int> cnt(26, 0);
for (char &c : s)
cnt[c - 'a']++;
string ans;
int cur = 0;
for (int i = 25, j = 24; i >= 0 && j >= 0;)
{
if (cnt[i] == 0) // 当前字符已经填完,填入后面的字符,重置 cur
{
i--;
cur = 0;
}
else if (cur < repeatLimit)
{
ans.push_back('a' + i);
cur++;
cnt[i]--;
}
else if (j >= i || cnt[j] == 0)
{
j--;
}
else // 当前字符已经超过限制,填入其他字符,并且重置 cur
{
ans.push_back('a' + j);
cnt[j]--;
cur = 0;
}
}
return ans;
}
};
// @lc code=end
结果:
复杂度分析:
时间复杂度:O(n+|Σ|),其中 n 为字符串 s 的长度,Σ 为字符集,因为 s 由小写英文字母组成,|Σ|=26。
空间复杂度:O(|Σ|)。Σ 为字符集,因为 s 由小写英文字母组成,|Σ|=26。