2182. Construct String With Repeat Limit
Difficulty: Medium
Topics: Hash Table, String, Greedy, Heap (Priority Queue), Counting
You are given a string s and an integer repeatLimit. Construct a new string repeatLimitedString using the characters of s such that no letter appears more than repeatLimit times in a row. You do not have to use all characters from s.
Return the lexicographically largest repeatLimitedString possible.
A string a is lexicographically larger than a string b if in the first position where a and b differ, string a has a letter that appears later in the alphabet than the corresponding letter in b. If the first min(a.length, b.length) characters do not differ, then the longer string is the lexicographically larger one.
Example 1:
- Input: s = "cczazcc", repeatLimit = 3
- Output: "zzcccac"
-
Explanation: We use all of the characters from s to construct the repeatLimitedString "zzcccac".
- The letter 'a' appears at most 1 time in a row.
- The letter 'c' appears at most 3 times in a row.
- The letter 'z' appears at most 2 times in a row.
- Hence, no letter appears more than repeatLimit times in a row and the string is a valid repeatLimitedString.
- The string is the lexicographically largest repeatLimitedString possible so we return "zzcccac".
- Note that the string "zzcccca" is lexicographically larger but the letter 'c' appears more than 3 times in a row, so it is not a valid repeatLimitedString.
Example 2:
- Input: s = "aababab", repeatLimit = 2
- Output: "bbabaa"
-
Explanation: We use only some of the characters from s to construct the repeatLimitedString "bbabaa".
- The letter 'a' appears at most 2 times in a row.
- The letter 'b' appears at most 2 times in a row.
- Hence, no letter appears more than repeatLimit times in a row and the string is a valid repeatLimitedString.
- The string is the lexicographically largest repeatLimitedString possible so we return "bbabaa".
- Note that the string "bbabaaa" is lexicographically larger but the letter 'a' appears more than 2 times in a row, so it is not a valid repeatLimitedString.
Constraints:
1 <= repeatLimit <= s.length <= 105-
sconsists of lowercase English letters.
Hint:
- Start constructing the string in descending order of characters.
- When repeatLimit is reached, pick the next largest character.
Solution:
We use a greedy approach to prioritize lexicographically larger characters while ensuring that no character exceeds the repeatLimit consecutively. The approach uses a priority queue (max heap) to process characters in lexicographically descending order and ensures that no character appears more than the repeatLimit times consecutively.
Solution Explanation
-
Count Characters: Count the frequency of each character in the string
susing an array. - Max Heap: Use a max heap (priority queue) to sort and extract characters in descending lexicographical order.
-
Greedy Construction:
- Add the largest character available up to
repeatLimittimes. - If the
repeatLimitfor the current character is reached, switch to the next largest character, insert it once, and then reinsert the first character into the heap for further use.
- Add the largest character available up to
- Edge Handling: Properly manage when a character cannot be used any further.
Let's implement this solution in PHP: 2182. Construct String With Repeat Limit
<?php
/**
* @param String $s
* @param Integer $repeatLimit
* @return String
*/
function repeatLimitedString($s, $repeatLimit) {
...
...
...
/**
* go to ./solution.php
*/
}
// Test Cases
echo repeatLimitedString("cczazcc", 3) . "\n"; // Output: zzcccac
echo repeatLimitedString("aababab", 2) . "\n"; // Output: bbabaa
?>
Explanation:
-
Frequency Count:
- Iterate through the string
sto count the occurrences of each character. - Store the frequency in an associative array
$freq.
- Iterate through the string
-
Sort in Descending Order:
- Use
krsort()to sort the characters by their lexicographical order in descending order.
- Use
-
Build the Result:
- Continuously append the lexicographically largest character (
$char) to the result string. - If a character reaches its
repeatLimit, stop appending it temporarily. - Use a temporary queue to hold characters that still have remaining counts but are temporarily skipped.
- Continuously append the lexicographically largest character (
-
Handle Repeat Limit:
- If the current character has hit the
repeatLimit, use the next lexicographically largest character from the queue. - Reinsert the previous character back into the frequency map to continue processing it later.
- If the current character has hit the
-
Edge Cases:
- Characters may not use up their full counts initially.
- After handling a backup character from the queue, the current character resumes processing.
How It Works
-
Character Count:
$freqkeeps track of occurrences for all characters. -
Max Heap:
SplPriorityQueueis used as a max heap, where characters are prioritized by their ASCII value (descending order). -
String Construction:
- If the current character has reached its
repeatLimit, fetch the next largest character. - Use the next largest character once and reinstate the previous character into the heap for future use.
- If the current character has reached its
-
Final Result: The resulting string is the lexicographically largest string that satisfies the
repeatLimitconstraint.
Example Walkthrough
Input:
s = "cczazcc", repeatLimit = 3
Steps:
Frequency count:
['a' => 1, 'c' => 4, 'z' => 2]Sort in descending order:
['z' => 2, 'c' => 4, 'a' => 1]-
Append characters while respecting
repeatLimit:- Append
'z'→ "zz" (zcount = 0) - Append
'c'3 times → "zzccc" (ccount = 1) - Append
'a'→ "zzccca" (acount = 0) - Append remaining
'c'→ "zzcccac"
- Append
Output: "zzcccac"
Time Complexity
- Character Frequency Counting: O(n), where n is the length of the string.
- Heap Operations: O(26 log 26), as the heap can hold up to 26 characters.
- Overall Complexity: O(n + 26 log 26) ≈ O(n).
Space Complexity
- O(26) for the frequency array.
- O(26) for the heap.
Test Cases
echo repeatLimitedString("cczazcc", 3) . "\n"; // Output: "zzcccac"
echo repeatLimitedString("aababab", 2) . "\n"; // Output: "bbabaa"
echo repeatLimitedString("aaaaaaa", 2) . "\n"; // Output: "aa"
echo repeatLimitedString("abcabc", 1) . "\n"; // Output: "cba"
Edge Cases
-
scontains only one unique character (e.g.,"aaaaaaa",repeatLimit = 2): The output will only include as many characters as allowed consecutively. -
repeatLimit = 1: The output alternates between available characters. - All characters in
sare unique: The output is sorted in descending order.
This implementation works efficiently within the constraints.
Contact Links
If you found this series helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!
If you want more helpful content like this, feel free to follow me:
Top comments (0)