Coding questions · Databricks
Implement run-length encoding and decoding
This question evaluates proficiency in string manipulation and encoding algorithms, specifically run-length encoding and decoding, along with attention to edge cases such as empty inputs and single-character runs and correct handling of repetition counts.
You are given a string consisting of lowercase English letters. You need to implement run-length encoding (RLE) and its corresponding decoding.
-
Encoding
- Input: a string
s, e.g.,"aaabccccd". - Output: an encoded string where each maximal group of consecutive identical characters is replaced by the character followed by the count of repetitions, e.g.,
"a3b1c4d1".
- Input: a string
-
Decoding
- Input: an RLE-encoded string as described above, which is always valid (i.e., alternates between characters and positive integer counts), e.g.,
"a3b1c4d1". - Output: the original string, e.g.,
"aaabccccd".
- Input: an RLE-encoded string as described above, which is always valid (i.e., alternates between characters and positive integer counts), e.g.,
Constraints:
0 <= len(s) <= 10^5for both encoding and decoding inputs.- Counts in the encoded string fit in a 32-bit signed integer.
Tasks:
- Describe how to implement
encode(String s)anddecode(String encoded). - Explain the time and space complexity of each function.
- Consider edge cases such as empty strings and runs of length 1.
Part 1: Implement Run-Length Encoding
Implement run-length encoding (RLE) for a string of lowercase English letters.
Given a string s, scan it left to right and replace each maximal group of consecutive identical characters (a "run") with that character followed immediately by the number of times it repeats in that run. Concatenate the encoded runs, in order, to form the result.
What to implement
solution(s) -> str
- Input: a string
scontaining only lowercase English letters (a–z). - Output: the run-length-encoded string.
Rules
- Process runs from left to right. A run ends as soon as a different character appears (or the string ends).
- Each run is encoded as
<character><count>, where<count>is the run length written in decimal. - The count is always written, even when it is
1. A single, isolated character becomes<char>1.
Examples
"aaabccccd"→"a3b1c4d1"(threea, oneb, fourc, oned)"a"→"a1""abc"→"a1b1c1"(every character is its own run of length 1)"zzzzzzzzzz"→"z10"
Edge case
- If
sis empty, return an empty string"".
Constraints
0 <= len(s) <= 10^5scontains only lowercase English letters.- Every run count fits in a 32-bit signed integer.
Hints
- Scan the string from left to right while tracking the current character and how many times it has repeated.
- When the character changes, append the previous character and its count to a result list, then start a new run.
Part 2: Implement Run-Length Decoding
Decode a run-length encoded string back into the original text.
You are given a valid run-length encoded string encoded. Reconstruct and return the original (decoded) string.
Encoding format
The encoded string is a sequence of runs, where each run is a lowercase English letter immediately followed by a positive integer count. The letter is the character to repeat, and the count is how many times it appears in the original string.
- The string strictly alternates between a single lowercase letter and its count.
- A count may span multiple digits (e.g.
z10means the letterzrepeated 10 times — notzfollowed by1then0).
What to implement
Implement solution(encoded), which takes the encoded string and returns the decoded string.
Example
Input: "a3b1c4d1"
Output: "aaabccccd"
This decodes as a×3, b×1, c×4, d×1, giving aaab + cccc + d = aaabccccd.
Edge case
- If
encodedis an empty string, return an empty string"".
Constraints
0 <= len(encoded) <= 10^5encodedis always a valid run-length encoding (every letter is followed by a positive integer count).- Each count fits in a 32-bit signed integer.
Hints
- Read one character at a time, then read all consecutive digits after it to form the full count.
- Appending pieces to a list and joining at the end is more efficient than repeated string concatenation.
Approach
The encoded string alternates between a single lowercase letter and a positive integer count (which may span several digits), e.g. a3b1c4d1. We decode it with a single left-to-right scan using a two-pointer technique.
Approach
- Empty input is handled up front: if
encodedis falsy we return''. - We keep an index
iand a listpartsthat collects decoded chunks. - At each step
encoded[i]is the letterch. We advanceipast it, then set a second pointerj = iand walk it forward whileencoded[j].isdigit()is true. This consumes the entire multi-digit count, so inputs likez10parse10, not1. int(encoded[i:j])turns that digit slice into the repeat count, andch * countbuilds the expanded run, which we push ontoparts.- We jump
i = jto the start of the next letter and repeat untilireaches the end. - Finally
''.join(parts)concatenates all runs into the original string.
Why it's correct The input is guaranteed valid and to strictly alternate letter→count, so every loop iteration reads exactly one letter followed by one full integer. Building runs in a list and joining once avoids repeated string-concatenation copies, which keeps the work proportional to the output size. Using a digit-scan rather than reading a single character is the key detail that makes multi-digit counts decode correctly.
- Time complexity: O(n + L), where n = len(encoded) and L = length of the decoded output. The scan visits each input character once (each char is read by
ior the digit pointerj), and building the runs writes L characters total; the final join is also O(L). - Space complexity: O(L) for the decoded result stored in
partsand the joined output. Auxiliary bookkeeping (pointers, the digit slice) is O(1) beyond that.