1868. Product of Two Run-Length Encoded Arrays
1868. Product of Two Run-Length Encoded Arrays
Difficulty: Medium
Category: Run-Length Encoding, Two Pointers, Array Processing
Problem Statement
Run-length encoding is a compression algorithm that allows for an integer array nums with many segments of repeated numbers to be represented by a (generally smaller) 2D array encoded. Each encoded[i] = [vali, freqi] describes the ith segment of repeated numbers in nums where vali is the value that is repeated freqi times.
For example, nums = [1,1,1,2,2,2,2,2] is represented by the run-length encoded array encoded = [[1,3],[2,5]]. Another way to read this is “three 1’s followed by five 2’s”.
The product of two run-length encoded arrays encoded1 and encoded2 is a run-length encoded array that represents the product of nums1 and nums2.
Given two run-length encoded arrays encoded1 and encoded2, both of length n, return the product of encoded1 and encoded2.
Note: Compression does not affect the product, and you can assume that the product of nums1 and nums2 does not exceed 10^9.
Examples
Example 1:
Input: encoded1 = [[1,3],[2,3]], encoded2 = [[6,3],[3,3]]
Output: [[6,6]]
Explanation: encoded1 represents [1,1,1,2,2,2] and encoded2 represents [6,6,6,3,3,3].
The product is [6,6,6,6,6,6], which is represented by [[6,6]].
Example 2:
Input: encoded1 = [[1,3],[2,1],[3,2]], encoded2 = [[2,3],[3,3]]
Output: [[2,3],[6,1],[9,2]]
Explanation: encoded1 represents [1,1,1,2,3,3] and encoded2 represents [2,2,2,3,3,3].
The product is [2,2,2,6,9,9], which is represented by [[2,3],[6,1],[9,2]].
Constraints
2 <= encoded1.length, encoded2.length <= 10^5encoded1[i].length == encoded2[j].length == 21 <= vali, freqi <= 10^4
Approach
The key insight is to process both encoded arrays simultaneously using two pointers, computing the product of corresponding elements and merging consecutive segments with the same value.
Algorithm:
- Use two pointers
iandjto traverse both encoded arrays - At each step, take the minimum frequency between the current segments
- Compute the product of the values and the minimum frequency
- If the result array is not empty and the last segment has the same value, merge frequencies
- Otherwise, add a new segment
- Decrease frequencies and advance pointers when segments are exhausted
Solution
class Solution {
public:
vector<vector<int>> findRLEArray(vector<vector<int>>& encoded1, vector<vector<int>>& encoded2) {
int i = 0, j = 0;
vector<vector<int>> rtn;
while(i < (int)encoded1.size() && j < (int)encoded2.size()) {
int freq = min(encoded1[i][1], encoded2[j][1]);
int val = encoded1[i][0] * encoded2[j][0];
encoded1[i][1] -= freq;
encoded2[j][1] -= freq;
if(!rtn.empty() && rtn.back()[0] == val) {
rtn.back()[1] += freq;
} else {
rtn.push_back({val, freq});
}
if(encoded1[i][1] == 0) i++;
if(encoded2[j][1] == 0) j++;
}
return rtn;
}
};
Explanation
Step-by-Step Process:
- Initialize pointers:
i = 0, j = 0to track positions in both arrays - Process segments: While both arrays have unprocessed segments:
- Take minimum frequency:
freq = min(encoded1[i][1], encoded2[j][1]) - Compute product:
val = encoded1[i][0] * encoded2[j][0] - Decrease frequencies: Subtract
freqfrom both current segments
- Take minimum frequency:
- Merge or add segment:
- If result is empty or last segment has different value: add new segment
- If last segment has same value: merge frequencies
- Advance pointers: Move to next segment when current frequency reaches 0
Example Walkthrough:
For encoded1 = [[1,3],[2,3]] and encoded2 = [[6,3],[3,3]]:
- Step 1:
min(3,3) = 3,val = 1*6 = 6, add[6,3] - Step 2:
min(3,3) = 3,val = 2*3 = 6, merge with previous:[6,6] - Result:
[[6,6]]
Complexity Analysis
Time Complexity: O(n + m) where n and m are the lengths of the encoded arrays
- Each segment is processed exactly once
- Merging operations are O(1)
Space Complexity: O(n + m) for the result array
- In worst case, no segments can be merged
Key Insights
- Two-pointer technique: Efficiently process both arrays simultaneously
- Frequency management: Always consume the minimum frequency to avoid gaps
- Segment merging: Combine consecutive segments with same values to maintain compression
- In-place modification: Modify input arrays to track remaining frequencies
This approach efficiently computes the product while maintaining the run-length encoded format and optimal compression.