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。