Decompress Run-Length Encoded List

🏠 ⬅️ ➡️

We are given a list nums of integers representing a list compressed with run-length encoding.

Consider each adjacent pair of elements [freq, val] = [nums[2*i], nums[2*i+1]] (with i >= 0). For each such pair, there are freq elements with value val concatenated in a sublist. Concatenate all the sublists from left to right to generate the decompressed list.

Return the decompressed list.

Example 1:

Input: nums = [1,2,3,4] Output: [2,4,4,4] Explanation: The first pair [1,2] means we have freq = 1 and val = 2 so we generate the array [2]. The second pair [3,4] means we have freq = 3 and val = 4 so we generate [4,4,4]. At the end the concatenation [2] + [4,4,4] is [2,4,4,4].

Example 2:

Input: nums = [1,1,2,3] Output: [1,3,3]

Constraints:

  • 2 <= nums.length <= 100
  • nums.length % 2 == 0
  • 1 <= nums[i] <= 100

Note: This problem is from LeetCode.
Compiled
Executed
Correct
program main
    implicit none

    integer, parameter :: n = 4
    integer, dimension(n) :: nums
    integer, dimension(n) :: expected
    integer, dimension(:), allocatable :: actual

    nums = [1, 2, 3, 4]
    expected = [2, 4, 4, 4]
    call test_case(nums, expected)

    nums = [1, 1, 2, 3]
    expected = [1, 3, 3]
    call test_case(nums, expected)

contains

    subroutine test_case(nums, expected)
        implicit none
        integer, dimension(:), intent(in) :: nums
        integer, dimension(:), intent(in) :: expected
        integer, dimension(:), allocatable :: actual

        allocate(actual, source=decompress(nums))

        if (size(actual) /= size(expected)) then
            write (*, '("Test case failed: ", "Expected size:", i0, &
                          &" Actual size:", i0)') size(expected), size(actual)
            stop 1
        end if

        if (any(actual /= expected)) then
            write (*, '("Test case failed: ", "Expected:", *(i0, ","), &
                          &" Actual:", *(i0, ","))') expected, actual
            stop 1
        end if

        deallocate(actual)
    end subroutine test_case

    function decompress(nums) result(decompressed)
        implicit none
        integer, dimension(:), intent(in) :: nums
        integer, dimension(:), allocatable :: decompressed
        integer :: i, j, k, freq, val

        k = 0
        do i = 1, size(nums), 2
            freq = nums(i)
            val = nums(i + 1)
            do j = 1, freq
                k = k + 1
                decompressed(k) = val
            end do
        end do
    end function decompress
end program main
Compiled
Executed
Correct
module RunLengthEncoding
  implicit none
contains
  function decompress(nums) result(decompressed)
    integer, intent(in) :: nums(:)
    integer :: decompressed(size(nums)/2)
    integer :: i, j, freq, val

    i = 1
    j = 1
    do while (i <= size(nums))
      freq = nums(i)
      val = nums(i+1)
      i = i + 2
      do while (freq > 0)
        decompressed(j) = val
        j = j + 1
        freq = freq - 1
      end do
    end do
  end function decompress
end module RunLengthEncoding

program main
  use RunLengthEncoding
  implicit none
  integer, parameter :: nums = [1, 2, 3, 4]
  integer :: decompressed(size(nums)/2)

  decompressed = decompress(nums)
  write (*,*) 'Decompressed list: ', decompressed
end program main
🌐 Data from online sources
MOD = 10**9 + 7

def add_rooms(idx, children, memo):
    if not children[idx]:
        return 1
    if memo[idx] != -1:
        return memo[idx]

    res = 1
    cnt = 0
    for child in children[idx]:
        cnt += 1
        res = (res * add_rooms(child, children, memo)) % MOD

    for i in range(2, cnt + 1):
        res = (res * i) % MOD

    memo[idx] = res
    return res

def num_of_ways(prev_room):
    n = len(prev_room)
    children = [[] for _ in range(n)]
    for i in range(1, n):
        children[prev_room[i]].append(i)

    memo = [-1] * n
    return add_rooms(0, children, memo)
  1. Create a function addRooms that takes the room index, the array that stores the room dependencies (children), and the memoization array as inputs.
  2. If there are no dependencies for the current room, return 1.
  3. If the memoization array already has the result for the current room, return it.
  4. Calculate the number of ways to create the directly connected rooms with the current room. Multiplying the results is possible because each new room is created after the current room is completed. Apply the modulo operator at each step.
  5. Factorial of the number of directly connected rooms need to be multiplied since they can be constructed in any order. Apply the modulo operator at each step.
  6. Store the result in the memoization array.
  7. Call the addRooms function with room 0 and return the result.
🌐 Data from online sources
#include <vector>
using namespace std;

const int MOD = 1e9 + 7;

int addRooms(int idx, const vector<vector<int>>& children, vector<int>& memo) {
    if (children[idx].empty()) return 1;

    if (memo[idx] != -1) return memo[idx];

    long long res = 1;
    int cnt = 0;
    for (int child : children[idx]) {
        cnt++;
        res = (res * addRooms(child, children, memo)) % MOD;
    }

    for (int i = 2; i <= cnt; i++) {
        res = (res * i) % MOD;
    }

    return memo[idx] = res;
}

int numOfWays(vector<int>& prevRoom) {
    int n = prevRoom.size();
    vector<vector<int>> children(n);
    for (int i = 1; i < n; i++) {
        children[prevRoom[i]].push_back(i);
    }

    vector<int> memo(n, -1);
    return addRooms(0, children, memo);
}
  1. Create a function addRooms that takes the room index, the array that stores the room dependencies (children), and the memoization array as inputs.
  2. If there are no dependencies for the current room, return 1.
  3. If the memoization array already has the result for the current room, return it.
  4. Calculate the number of ways to create the directly connected rooms with the current room. Multiplying the results is possible because each new room is created after the current room is completed. Apply the modulo operator at each step.
  5. Factorial of the number of directly connected rooms need to be multiplied since they can be constructed in any order. Apply the modulo operator at each step.
  6. Store the result in the memoization array.
  7. Call the addRooms function with room 0 and return the result.