Facebook Pixel

1313. Decompress Run-Length Encoded List

Problem Description

You are given a list of integers called nums that represents data compressed using run-length encoding.

The list is organized in pairs where every two consecutive elements form a pair: [frequency, value]. Specifically:

  • nums[0] is the frequency and nums[1] is the value for the first pair
  • nums[2] is the frequency and nums[3] is the value for the second pair
  • And so on...

For each pair [freq, val], you need to expand it by repeating the value val exactly freq times.

Your task is to decompress the list by:

  1. Taking each frequency-value pair from the compressed list
  2. Repeating each value according to its frequency
  3. Concatenating all the repeated values in order to form the decompressed list

For example, if nums = [1, 2, 3, 4]:

  • First pair: frequency = 1, value = 2 → generates [2]
  • Second pair: frequency = 3, value = 4 → generates [4, 4, 4]
  • Final decompressed list: [2, 4, 4, 4]

The solution uses a list comprehension that iterates through the array in steps of 2 (to process pairs), and for each pair at index i, it repeats nums[i+1] (the value) exactly nums[i] (the frequency) times.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The problem is essentially asking us to reverse a compression technique. When we see run-length encoding, we're looking at a pattern where data is stored as (count, value) pairs. The natural way to decompress this is to simply follow the encoding rules in reverse.

Since the input array alternates between frequencies and values, we need to process the array two elements at a time. Every even index (0, 2, 4, ...) contains a frequency, and every odd index (1, 3, 5, ...) contains the corresponding value to repeat.

The key insight is that we can iterate through the array with a step size of 2 to grab each pair. For indices i = 0, 2, 4, ..., we have:

  • nums[i] is the frequency (how many times to repeat)
  • nums[i+1] is the value to repeat

Python's list comprehension provides an elegant way to express this decompression in a single line. We can use a nested loop structure where:

  • The outer loop moves through pairs: for i in range(0, len(nums), 2)
  • The inner loop repeats the value: for _ in range(nums[i])

This directly translates the problem's requirement into code: for each frequency-value pair, generate frequency copies of value, and collect all results in order. The underscore _ in the inner loop indicates we don't actually use the loop variable - we just need to repeat the operation nums[i] times.

Solution Approach

The solution follows a simulation approach where we directly implement the decompression process described in the problem.

The implementation uses a list comprehension with nested iteration:

return [nums[i + 1] for i in range(0, len(nums), 2) for _ in range(nums[i])]

Let's break down how this works:

  1. Outer iteration: for i in range(0, len(nums), 2)

    • This iterates through the array with a step of 2, visiting indices 0, 2, 4, and so on
    • Each i represents the starting index of a frequency-value pair
  2. Inner iteration: for _ in range(nums[i])

    • For each pair, this loop runs nums[i] times (the frequency)
    • The underscore _ indicates we don't use the loop variable itself
  3. Value generation: nums[i + 1]

    • For each iteration of the inner loop, we add nums[i + 1] (the value) to our result list

The algorithm processes each pair sequentially from left to right:

  • At index i, we read the frequency: freq = nums[i]
  • At index i+1, we read the value: val = nums[i+1]
  • We then add val to the result list freq times

For example, with nums = [2, 5, 1, 3]:

  • First pair (i=0): frequency = 2, value = 5 → adds [5, 5]
  • Second pair (i=2): frequency = 1, value = 3 → adds [3]
  • Final result: [5, 5, 3]

The time complexity is O(n × m) where n is the length of the input array and m is the average frequency value, since we need to generate output elements based on the frequencies. The space complexity is O(k) where k is the total number of elements in the decompressed list.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with nums = [2, 3, 1, 5, 2, 4].

Step 1: Identify the frequency-value pairs

  • Pair 1: frequency = 2 (index 0), value = 3 (index 1)
  • Pair 2: frequency = 1 (index 2), value = 5 (index 3)
  • Pair 3: frequency = 2 (index 4), value = 4 (index 5)

Step 2: Process each pair using our list comprehension

The outer loop for i in range(0, len(nums), 2) gives us i = 0, 2, 4.

When i = 0:

  • nums[0] = 2 (frequency)
  • nums[1] = 3 (value)
  • Inner loop runs 2 times, adding 3 each time
  • Contributes: [3, 3]

When i = 2:

  • nums[2] = 1 (frequency)
  • nums[3] = 5 (value)
  • Inner loop runs 1 time, adding 5
  • Contributes: [5]

When i = 4:

  • nums[4] = 2 (frequency)
  • nums[5] = 4 (value)
  • Inner loop runs 2 times, adding 4 each time
  • Contributes: [4, 4]

Step 3: Concatenate all contributions The list comprehension automatically concatenates these in order: [3, 3] + [5] + [4, 4] = [3, 3, 5, 4, 4]

Final Result: [3, 3, 5, 4, 4]

This demonstrates how the solution efficiently decompresses the run-length encoded data by processing pairs and expanding each value according to its frequency.

Solution Implementation

1class Solution:
2    def decompressRLElist(self, nums: List[int]) -> List[int]:
3        """
4        Decompress a run-length encoded list.
5      
6        The input list contains pairs [frequency, value] at even and odd indices.
7        For each pair, the value is repeated 'frequency' times in the output.
8      
9        Args:
10            nums: Run-length encoded list where nums[2i] is frequency and nums[2i+1] is value
11          
12        Returns:
13            Decompressed list with values repeated according to their frequencies
14        """
15        # Initialize result list
16        result = []
17      
18        # Iterate through the list in steps of 2 to process each (frequency, value) pair
19        for i in range(0, len(nums), 2):
20            frequency = nums[i]      # Extract frequency at even index
21            value = nums[i + 1]      # Extract value at odd index
22          
23            # Append the value 'frequency' times to the result
24            for _ in range(frequency):
25                result.append(value)
26      
27        return result
28
1class Solution {
2    /**
3     * Decompresses a run-length encoded list.
4     * The input array represents pairs where:
5     * - nums[2i] = frequency (how many times to repeat)
6     * - nums[2i+1] = value (the value to repeat)
7     * 
8     * @param nums The run-length encoded array
9     * @return The decompressed array
10     */
11    public int[] decompressRLElist(int[] nums) {
12        // List to store the decompressed values
13        List<Integer> decompressedList = new ArrayList<>();
14      
15        // Process pairs of elements (frequency, value)
16        for (int i = 0; i < nums.length; i += 2) {
17            int frequency = nums[i];
18            int value = nums[i + 1];
19          
20            // Add the value 'frequency' times to the result list
21            for (int j = 0; j < frequency; j++) {
22                decompressedList.add(value);
23            }
24        }
25      
26        // Convert the list to an array and return
27        return decompressedList.stream()
28                               .mapToInt(Integer::intValue)
29                               .toArray();
30    }
31}
32
1class Solution {
2public:
3    vector<int> decompressRLElist(vector<int>& nums) {
4        vector<int> result;
5      
6        // Process the RLE-encoded list in pairs (frequency, value)
7        for (int i = 0; i < nums.size(); i += 2) {
8            int frequency = nums[i];      // First element of pair: how many times to repeat
9            int value = nums[i + 1];      // Second element of pair: the value to repeat
10          
11            // Add 'value' to result 'frequency' times
12            for (int j = 0; j < frequency; j++) {
13                result.push_back(value);
14            }
15        }
16      
17        return result;
18    }
19};
20
1/**
2 * Decompresses a run-length encoded list.
3 * The input array contains pairs where nums[2i] is the frequency and nums[2i+1] is the value.
4 * 
5 * @param nums - The run-length encoded array where pairs represent [frequency, value]
6 * @returns The decompressed array with values repeated according to their frequencies
7 */
8function decompressRLElist(nums: number[]): number[] {
9    const result: number[] = [];
10  
11    // Process the array in pairs (frequency, value)
12    for (let i = 0; i < nums.length; i += 2) {
13        const frequency: number = nums[i];
14        const value: number = nums[i + 1];
15      
16        // Add the value to result array 'frequency' times
17        for (let j = 0; j < frequency; j++) {
18            result.push(value);
19        }
20    }
21  
22    return result;
23}
24

Time and Space Complexity

The time complexity is O(m), where m is the total number of elements in the decompressed output. While we traverse the input array nums of length n once (iterating through pairs), for each frequency-value pair (nums[i], nums[i+1]), we perform nums[i] iterations in the inner loop to generate the output elements. The total work done is proportional to the sum of all frequencies, which equals the output size.

The space complexity is O(1) if we exclude the space required for the output list. The list comprehension only uses a constant amount of extra space for loop variables i and the implicit iterator. If we include the output space, the space complexity would be O(m), where m is the total number of elements in the decompressed result.

Note: The reference answer states O(n) for time complexity, which considers only the traversal of the input array. However, a more precise analysis should account for the total number of elements generated, as each frequency nums[i] contributes nums[i] iterations to the overall time complexity.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Index Out of Bounds Error

One common pitfall occurs when the input array has an odd number of elements. Since the algorithm expects pairs of [frequency, value], accessing nums[i+1] when i is the last index will cause an IndexError.

Problem Example:

nums = [2, 5, 3]  # Odd number of elements - incomplete pair
# When i=2, trying to access nums[3] causes IndexError

Solution: Add validation to ensure the input has an even number of elements:

def decompressRLElist(self, nums: List[int]) -> List[int]:
    if len(nums) % 2 != 0:
        raise ValueError("Input must contain complete frequency-value pairs")
  
    result = []
    for i in range(0, len(nums), 2):
        frequency = nums[i]
        value = nums[i + 1]
        for _ in range(frequency):
            result.append(value)
    return result

2. Memory Overflow with Large Frequencies

If the frequency values are extremely large, the decompressed list could consume excessive memory, potentially causing memory errors.

Problem Example:

nums = [1000000000, 1, 1000000000, 2]  # Would create 2 billion elements

Solution: Consider using a generator for memory-efficient processing or add a safety check:

def decompressRLElist(self, nums: List[int]) -> List[int]:
    MAX_OUTPUT_SIZE = 10**6  # Set reasonable limit
    total_size = sum(nums[i] for i in range(0, len(nums), 2))
  
    if total_size > MAX_OUTPUT_SIZE:
        raise ValueError(f"Output size {total_size} exceeds maximum allowed")
  
    result = []
    for i in range(0, len(nums), 2):
        frequency = nums[i]
        value = nums[i + 1]
        result.extend([value] * frequency)  # More efficient than loop
    return result

3. Negative or Zero Frequencies

The algorithm doesn't explicitly handle negative frequencies, which could lead to unexpected behavior or silent errors.

Problem Example:

nums = [-1, 5, 0, 3, 2, 7]  # Negative and zero frequencies

Solution: Add validation for non-negative frequencies:

def decompressRLElist(self, nums: List[int]) -> List[int]:
    result = []
    for i in range(0, len(nums), 2):
        frequency = nums[i]
        if frequency < 0:
            raise ValueError(f"Frequency cannot be negative: {frequency}")
      
        value = nums[i + 1]
        result.extend([value] * frequency)  # Zero frequency naturally produces no output
    return result

4. Performance Inefficiency with Multiple Appends

Using repeated append() calls in a loop can be less efficient than using list multiplication or extend().

Inefficient approach:

for _ in range(frequency):
    result.append(value)  # Multiple individual appends

Optimized approach:

result.extend([value] * frequency)  # Single extend operation
# OR use list comprehension as in the original solution
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which data structure is used to implement priority queue?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More