给你一个字符串 s 和一个整数 repeatLimit ,用 s 中的字符构造一个新字符串 repeatLimitedString ,使任何字母 连续 出现的次数都不超过 repeatLimit 次。你不必使用 s 中的全部字符。
返回 字典序最大的 repeatLimitedString 。
如果在字符串 a 和 b 不同的第一个位置,字符串 a 中的字母在字母表中出现时间比字符串 b 对应的字母晚,则认为字符串 a 比字符串 b 字典序更大 。如果字符串中前 min(a.length, b.length) 个字符都相同,那么较长的字符串字典序更大。
示例 1:
输入:s = "cczazcc", repeatLimit = 3
输出:"zzcccac"
解释:使用 s 中的所有字符来构造 repeatLimitedString "zzcccac"。
字母 'a' 连续出现至多 1 次。
字母 'c' 连续出现至多 3 次。
字母 'z' 连续出现至多 2 次。
因此,没有字母连续出现超过 repeatLimit 次,字符串是一个有效的 repeatLimitedString 。
该字符串是字典序最大的 repeatLimitedString ,所以返回 "zzcccac" 。
注意,尽管 "zzcccca" 字典序更大,但字母 'c' 连续出现超过 3 次,所以它不是一个有效的 repeatLimitedString 。
示例 2:
输入:s = "aababab", repeatLimit = 2
输出:"bbabaa"
解释:
使用 s 中的一些字符来构造 repeatLimitedString "bbabaa"。
字母 'a' 连续出现至多 2 次。
字母 'b' 连续出现至多 2 次。
因此,没有字母连续出现超过 repeatLimit 次,字符串是一个有效的 repeatLimitedString 。
该字符串是字典序最大的 repeatLimitedString ,所以返回 "bbabaa" 。
注意,尽管 "bbabaaa" 字典序更大,但字母 'a' 连续出现超过 2 次,所以它不是一个有效的 repeatLimitedString 。
提示:
1 <= repeatLimit <= s.length <= 10^5
s 由小写英文字母组成
解题思路
贪心处理,每次加RepeatLimit个最大的字母,然后加一个次大的字母。直到没有字母可加。
-spec repeat_limited_string(S :: unicode:unicode_binary(), RepeatLimit :: integer()) -> unicode:unicode_binary().
repeat_limited_string(S, RepeatLimit) ->
L = binary_to_list(S),
Tree = gb_trees:empty(),
NewTree = lists:foldl(fun(Key, Acc) ->
case gb_trees:lookup(Key, Acc) of
{value, Value} ->
gb_trees:update(Key, Value + 1, Acc);
_ ->
gb_trees:insert(Key,1, Acc)
end
end, Tree, L),
do_repeat(1, RepeatLimit, NewTree, [])
.
do_repeat(0, Limit, Tree, List) ->
list_to_binary(lists:reverse(List));
do_repeat(1, Limit, Tree, List) ->
case gb_trees:size(Tree) of
0 ->
do_repeat(0, Limit, Tree, List);
1 ->
{Key, Value, Tree1} = gb_trees:take_largest(Tree),
Min = min(Value, Limit),
L = lists:duplicate(Min, Key),
do_repeat(0, Limit, Tree1, L ++ List);
_ ->
{Key1, Value1, Tree1} = gb_trees:take_largest(Tree),
Min = min(Value1, Limit),
L = lists:duplicate(Min, Key1),
List1 = L ++ List,
if
Value1 > Min ->
{Key2, Value2, Tree2} = gb_trees:take_largest(Tree1),
Tree3 = gb_trees:insert(Key1,Value1 - Min, Tree2),
if
Value2 > 1 ->
Tree4 = gb_trees:insert(Key2,Value2 - 1, Tree3);
true ->
Tree4 = Tree3
end,
do_repeat(1, Limit, Tree4, [Key2 | List1]);
true ->
do_repeat(1, Limit, Tree1, List1)
end
end.